Хабрахабр

Конспект доклада «Монолит для сотен версий клиентов» (HL2018, Badoo, Владимир Янц)

Продолжаю серию конспектов с HL2018. В проверке этого конспекта мне помогали ребята из Badoo (Владимир Янц vyants и Николай Крапивный), за что им большой спасибо. Надеюсь, это положительно сказалось на качестве донесения идеи доклада.

image

Особенности процесса разработки:

Ответственность разработчика не заканчивается релизом бэкенда. Он отвечает до реализации на платформах.

image

Мы чаще всего не в курсе когда клиенты начнут это имплементировать. Есть ручное тестирование, но клиент не готов к моменту релиза и выпускается с (непредсказуемой) задержкой. Поэтому тестировать руками тяжело и не все можно. Иногда (не часто) фичи начинают делать через большой срок. Поэтому нужны автотесты.

Тесты

Unit тесты

Пишутся на phpunit.

Не ходят ни в базу, ни в сервисы (не должны ни с чем взаимодействовать). Тестируют малую единицу.

Легаси до сих пор есть и усложняет процесс тестирование.

Разработали библиотеку softMocks — перехватывает все include / require и подменяет на изменённый.

Можно мотать любые методы: статические, приватные, финальные.
Библиотека доступна в опен сорс.

Проблема: softmocks расслабляют и дают писать не тестируемый код (и все аврно покрыть его тестами).

Приняли правила:

  • Новый код должен быть легко тестируем phpunit
  • SoftMocks — крайний случай (старый код /долго / дорого / сложно)

На эти правила смотрим на код ревью

Качество тестов

Мутационное тестирование

  • Берём код
  • Берём code coverage
  • Парсим код и применяем мутации (меняем + => -; true => false и тп.)
  • Для каждой мутации прогоняем сюит (набор) тестов.
  • Если тесты упали, то ок. Если нет — они недостаточно эффективны. Разбираемся, меняем / дописываем тесты.

Есть готовые решения (Humbug, Infection), но они не подошли (не совместимы с softmocks, есть сложности с code coverage). Поэтому написали свое.

Доступно для запуска в ручную, из консоли. Мутационное тестирование пока недоступном для ручного теста. Результат будет на хабре. Сейчас внедряем в CI pipeline, выстраиваем процесс.

Интеграционные тесты

Тестируем работу нескольких компонентов в связке; проверяем работу с базой и/или сервисами.

Стандартный подход к тестированию БД (DBUnit):

  1. Поднимаем тестовую БД
  2. Заполняем ее
  3. Запускаем тест
  4. Очищаем БД

Проблемы:

  • Нужно поддерживать datatables и dataset (актуальность содержимого БД)
  • Требуется время на подготовку бд
  • Параллельные запуски делают тесты нестабильными и порождают дедлоки

Решение: библиотека DBMocks (своё решение)

Принцип работы:

  • Методы драйверов dB перехватываются с помощью SoftMocks на setUp теста
  • Из запроса парсим db + table
  • В tmpfs создаются временные таблицы с такой же схемой
  • Все запросы ходят только во временные таблицы
  • На TearDown они удаляются

Библиотека небольшая, но пока не запушена в опен сорс

Результаты:

  • Тесты не могут повредить данные в оригинальных таблицах
  • Тесты изолированы друг от друга (можно запускать параллельно)
  • Тестируется совместимость запроса с версией MySQL

API тесты

  • Имитируют клиентскую сессию
  • Умеют слать запросы к бэкенду
  • Бэкенд отвечает почти как реальному клиенту

Обычно такие тесты требуют авторизованного пользователя. Его нужно создать перед тестом и удалить после. Это вносит дополнительные риски (репликация, фоновые задачи).

Научились их очищать. Решение: Сделали пул тестовых пользователей.

image

Нужно изолировать тестовых и живых пользователей. Тестовые пользователя находятся в одном окружении с реальными, потому что devel != prod.

И эти пользователи также исключаются из аналитики и результатов a/b тестов. Для изоляции добавили флаг is_test_user у пользователя.

Можно сделать дешевле — отправить тестовых пользователей «в Антарктиду», где их никто не увидит (кроме пингвинов).

QA API

Инструмент для подготовки окружения в api тестах, по сути бекдор в бэкенде для быстрого изменения параметров пользователя / среды.

  • Хорошо документированные апи методы
  • Быстро и легко управляют данные
  • Пишут backend разработчики
  • Можно применять только к тестовым пользователям

Позволяют изменить пользователю неизменяемые данные (например, дату регистрации).

Требуется защита:

  • На уровне сети (доступно только из офисной сети)
  • С каждым запросом передаётся secret, валидность которого проверяется
  • Методы работают только с тестовыми пользователями

Есть BugsBounty программа на HackerOne. Платят за найденные уязвимости. Один косяк с QA API нашли с ее помощью.

Remote mocks

Моки для удаленного бэкенда.

Тест просит backend инициализировать для сессии mock. Работают на Базе soft mocks. При получении запроса бэкенд проверяет список моков для сессии и применяет их при помощи SoftMocks.

Пример теста:

image

Есть соблазн писать их вместо Unit. API тесты слишком удобны. Но API тесты сильно медленее.

Приняли набор правил:

  • Цель АПИ тестов — тестировать протокол и правильность интеграции
  • Допустимо проверять сложные флоу
  • Нельзя тестировать мелкую вариативность
  • На code review проверяем тесты тоже.

Ui тесты

Не пишет бэкенд команда.

Для мобильных calabash. Фича покрывается Ui тестами когда стабилизируется.
Используется selenium для веб.

Прогон тестов

100 000 юнит тестов. 6 000 интеграционных, 14 000 апи тестов.
В 1 поток время 40 мин / 90 мин / 10 часов.

Сделали TestCloud — облако для запуска тестов.

image

Распределение теста между потоками:

  • Можно поровну (плохо, все тесты разные, получается неравные по времени части)
  • Запустить несколько потоков и последовательно скармливать тесты phpunit по одному (накладные расходы на инициализацию. Долго!)

Решение:

  • Сбор статистики по времени прогона.
  • Компоновка тестов так, чтобы чанк прогонялся не больше 30 секунд

Проблема с апи тестами — долго, много ресурсов и не дают выполнится другим.

Для решения разбили cloud на 2 части:

  1. Запускает только быстрые тесты
  2. Запускает оба типа тестов.

Результат — ускорение времени до:

  • Unit — 1 мин
  • Интеграционные — 5 мин
  • API — 15 минут.

Прогон по code coverage

Какие тесты выполнять? Покажет code coverage.

  1. Получаем branch diff
  2. Формируем список изменённых файлов
  3. Получаем список тестов для этих файлов
  4. запускаем прогон сюита только из этих тестов.

Coverage формируется раз в сутки, ночью, для master-ветки. Результаты (diff) складываем в базу.

Плюсы:

  • Меньше тестов прогоняем: меньше нагрузка на железо и обратная связь от тестов быстрее
  • Можно запускать тесты для патчей. Это позволяет быстро выкатить хотфикс. В патчах скорость важнее всего.

Минусы:

  • Релиз бэкенд 2 раза в день. После обеда coverage менее актуален (но при выкате била всегда гоняем полный сьют).
  • Апи тесты генерируют обширный coverage. Для них этот подход не дает большой экономии.

Если разработчику нужно сразу посмотреть code-coverage, то есть тулза которую можно запустить в консоле и сразу получить свежую метрику по coverege конкретного файла/компонента.
Считается хитро: берется данные по coverege мастера, добавляются все измененную тесты, получается маленький сьют по которому уже и считается покрытие.

Итоги

  • Нужны все уровни тестов
  • Количество != качество. Делайте Code review и мутационное тестирование
  • Изолируйте тестовых пользователей от реальных
  • Бэкдоры в бэкенде упрощают и ускоряют написание тестов
  • Собирайте статистику по тестам.

Ссылки

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть