Тестирование Big Data: вызов принят
Всем привет! Меня зовут Дмитрий Собко, и я занимаюсь тестированием больше 7 лет. Начинал свою карьеру с должности Junior Manual QA на проекте по разработке Android-приложения. Также был Automation Lead команды, которая разрабатывает приложение big data на стеке GCP (Google Cloud Platform). И именно эти опытом хотел бы поделиться.
В статье рассмотрены особенности тестирования именно приложений big data, которое немного отличается от тестирования REST API, UI и тем более Android/iOS. В то же время, зная основные моменты, можно построить достойный процесс контроля качества даже таких, на первый взгляд, нетестируемых решений.
Что такое big data
I keep saying that the sexy job in the next 10 years
will be statisticians, and I’m not kidding.
Hal Varian, chief economist at Google
Big data — это понятие, о котором, наверное, слышали уже все. Google Trends показывает, что интерес к big data возник примерно в 2012 году и не стихает до сих пор.
Чтобы определиться, что же такое big data, используем Google и находим следующие объяснения:
- это просто много данных (> 10 Тбайт);
- это настолько большие таблицы, что их невозможно открыть и проанализировать в Excel;
- это неструктурированные данные из разных источников, разного объема, которые показывают, как ведут себя наши кастомеры и т. д.
Мне больше всего нравится определение из Википедии:
Big data — это область, которая определяет способы анализа, систематического извлечения информации или, иными словами, имеет дело с набором данных, которые слишком большие или сложные для традиционных программных способов обработки.
Существует и так называемая 3V-теорема, раскрывающая суть термина big data с другой стороны.
Volume — объем данных. Он действительно большой. Обычно это больше 50 Тбайт и до бесконечности.
Velocity — данные регулярно обновляются, поэтому требуется их постоянная обработка (от batch processing, когда данные загружаются пакетами, например раз в сутки, до real time streaming, когда данные в реальном времени попадают на графики / в отчеты и даже влияют на системы принятия решений на основе ML).
Variety — разнообразные данные могут иметь абсолютно разные форматы, быть неструктурированными или структурированными частично (от CSV/Avro-файлов с четкой структурой до логов в потоке).
Путь в Cloud
Со временем хранить такие объемы данных на собственных или арендованных серверах становится все сложнее и дороже. И когда в
В 2019 году достаточно взглянуть на этот график:
В
Одной из компаний, которая наиболее подробно описывала путь от собственной инфраструктуры к Google Cloud, является Spotify. В ее блоге подробно рассказывается, почему были выбраны те или иные решения. Рекомендую почитать всем, кто интересуется этой темой.
И немного о Cloud-провайдерах:
Каждое третье приложение в клауде приходится на AWS. Azure от Microsoft и Google Cloud Platform соответственно лидеры оставшегося сегмента. Сопоставив эти два графика, можно сделать вывод, что изучение Cloud-технологий в целом и AWS в частности для тех, кто пока далек от этого, в том числе для QA-инженеров, становится скорее необходимостью, чем возможным желанием.
Как вообще выглядит проект big data
Обычный проект big data выглядит (очень упрощенно) следующим образом:
- На вход приложения попадают разные данные из разных источников. Обычно таких источников два:
- streaming (потоковые) данные — любая message queue (Kafka, Google PubSub, Amazon SNS и пр.);
- batch (пакетные) данные — обычно CSV, TXT, Avro, JSON-файлы.
- Данные извлекаются и складываются в Staging-таблицы. На этом этапе также возможна дедубликация, отдельная обработка записей, которые мы не смогли распарсить, и т. д. По сути, это настоящие source-данные as is.
- Дальше данные из Staging-таблиц трансформируются, группируются, фильтруются, дополняются метаданными и попадают в DWH (Data Warehouse), или в так называемый Target layer. Эти данные уже структурированы (например, имеют одинаковый формат полей с датой), и таблицы также имеют структурные связи между собой. Подробнее можно почитать здесь. В случае Google Cloud Platform это может быть BigQuery. У Amazon это Redshift. Но также это может быть Oracle, PostgreSQL и т. д.
- На основе данных в DWH формируются аналитические отчеты / принимаются решения
ML-системами. В самом простом случае на выходе у нас:- набор данных, на основе которых уже строится визуализация (Tableau, Power BI, Zoomdata и пр.);
- отчеты в виде CSV-файлов, которые отправляются, например, на SFTP-сервер или на S3-бакет.
Пример data pipeline на Google Cloud Platform
На входе данные поступают в виде batch-файлов или потоков (stream).
С помощью фреймворка Cloud dataflow данные извлекаются, трансформируются, обрабатываются и загружаются в DWH. В данном примере в основе DWH лежит BigQuery.
На основе полученных данных строится аналитика Cloud Machine Learning, Data Studio, возможная визуализация (Third-Party Tools) и т. д. Также в данном примере для кеширования данных используется Cloud Bigtable.
А как это протестировать
Как видно, здесь нет в чистом виде ни back-end- (API), ни front-end-частей. То есть у нас есть:
- входные данные, которые мы практически не можем проконтролировать;
- data processing (программная часть, которая отвечает за ETL — extract, transform, load);
- таблицы/файлы/визуализация на выходе.
Очевидно, что в данном случае end-to-end-тест — это проверка, успешно ли, например, строчка из CSV-файла на входе прошла все трансформации и корректно ли отображается в отчете. В идеале, конечно же, нам надо проверить, все ли входные данные корректно отображаются в итоговых отчетах.
Подходы к тестированию
Тестирование на моках/стабах
В этом случае мы проверяем корректность трансформаций, выгрузки на mocked-данных. Например, используем CSV с несколькими строками на входе. Отдельно проводим негативное тестирование
Тестирование на реальных данных
В таком случае мы пишем тесты для реальных данных, только догадываясь, сколько их будет и какими они будут. Допустим, мы знаем, что все кастомеры из CSV Customers на входе из страны Ukraine должны попасть в staging-таблицу customers_stage с кодом страны UA, а уже оттуда — в таблицу super_customers в Target-слой. Соответственно, мы и пишем такие тесты, опираясь на те данные, которые к нам пришли реально, и отталкиваясь от них.
Микс двух подходов
Unit/Integration-тесты пишем с использованием mocks/stubs. Также пару функциональных (end-to-end) тестов пишем для проверки реальной ситуации на энвайронменте с реальными данными. По моему мнению, этот подход является самым оптимальным, поскольку позволяет получить уверенность, что все хорошо идет на проде. И при этом при разработке новых фич он позволяет с помощью Unit/Integration-тестов быстро убедиться, что нет регрессии и вся логика построена правильно. Кроме того, на проде, конечно же, должна работать система мониторинга со сбором разнообразных метрик и отправкой нотификаций/алертов и пр.
Виды тестирования
Основных видов тестирования два: нефункциональное и функциональное. Нефункциональное тестирование включает в себя тестирование производительности, безопасности, нагрузочное и пр. В этом разделе мы коснемся функционального тестирования, которое, в свою очередь, делится на четыре вида.
Metadata Testing
Проверяем метаданные собственно данных (длину, тип) и таблиц (дату изменения, дату создания, количество строк, индексы и пр.).
Data Validation Testing
Проверяем, корректно ли данные прошли все трансформации. В качестве примера можно использовать преобразование Unix-тайм-стампа к дате.
Completeness (Reconciliation) Testing
Проверяем, все ли source-данные корректно обработаны. (Данные, которые успешно распарсились, попали в staging-слой, а если нет, то в error-таблицы или просто записались в логи.)
Accuracy Testing
Проверяем корректность логики трансформаций таблиц по пути от staging до analytics-слоя. (Обычно это делается путем создания с помощью SQL соответствующих проверочных view.)
А как это все автоматизировать
Для Unit/Integration-тестов можно легко использовать JUnit/TestNG (в случае Java-кода). Для Scala и GCP интересной альтернативой может быть библиотека Scio от того же Spotify.
Для функциональных тестов в нашем случае оптимальной была связка Kotlin + Spring + Cucumber BDD.
С помощью BDD-подхода мы наиболее точно и лаконично описывали все манипуляции с данными в рамках тестов. И при этом тест-репортами пользовались также дата-аналитики.
Почему Kotlin? Как мне кажется, это сейчас один из самых интересных JVM-языков для использования в том числе в автотестах. Есть много фишек, отличающих его от Java в лучшую сторону. Для тестировщиков, знающих Java/Groovy, переход будет очень легким. Ну и по состоянию на 2019 год можно уже смело утверждать, что этот язык перерос большинство детских болезней и продолжает развиваться.
Spring использовали для Dependency injection и еще нескольких приятных особенностей.
Позитивные итоги
Big data — это та область, которая почти наверняка будет развиваться, и узкоспециализированные технологии будут быстро и активно совершенствоваться. Кроме того, все больше компаний/проектов, которые обходили этот аспект своей деятельности стороной, будут обращать на него внимание.
Тестирование приложения big data непривычно, ставит перед QA много вызовов, которые нужно принимать и можно уверенно решать. И вместе с тем это интересно.
Спасибо за внимание!