Инфраструктура тестирования обсуждается реже чем проблемы программирования или шестизначные зарплаты. Дьявол кроется в деталях, а если точнее, то дьявол сидит в процессах внутри команды. В небольших командах процессы устраиваются сами собой без обсуждения. Продуктивность команды снижается по мере роста команды и в условиях игнорирования процессов. Статью будет полезно прочитать, если команда испытывает следующие трудности:
тестирование становится бутылочным горлышком и замедляет работу;
в продукт баги проникают чаще чем хотелось.
Процесс
Классический процесс в микрокоманде на ранних этапах выглядит следующим образом:
Шаги с первого по четвертый не стоят обсуждения, сразу перейдем к шагу номер пять. Чаще в микрокомандах тестировщик не разворачивает проект локально и не переключается на нужную ветку. Тестирование проходит на тестовом сервере, который соответствует ветке develop.
Процесс выстроен логично, но давайте пофантазируем насчет ожидаемых проблем. Если задача сложная и цикл тестирования и внесения изменений продолжительный, то такая задача тормозит остальные задачи и разработчики либо сделает релиз гораздо позже, либо будут мерджить небольшие задачи напрямую в ветку master.
Получается нечто вроде конвейера, если на ленте (dev-server) застряла Feature 6, это блокирует конвейер и предприятие останавливается. Согласно теории ограничений, это классическое бутылочное горлышко. Выпуск релиза будет отложен ровно на столько, сколько требуется на исправление проблем в Feature 6. Если однажды Feature 6 попала в ветку develop, остальные задачи (Feature 4, Feature 5) будут ожидать исправления ошибок в Feature 6. При таком подходе, трудно делать релизы вовремя, будут задачи, которые блокируют релиз.
Если внимательно посмотреть на схему, очевидное решение – сливать в ветку develop только готовые задачи, для этого код должен быть протестирован. Для тестировщика или менеджера затруднительно разворачивать локально проект и переключаться с одной ветки на другую. Следовательно, для каждой разрабатываемой задачи необходим собственный сервер с публичным доступом. Попробуем!
Теперь, разработчик для каждой задачи или состояния проекта имеет свой собственный домен и может отправить его тестировщику. При этом, если в коде есть какие-то проблемы, это не заблокирует релиз, так как проблемный код еще не попал в develop ветку. Значит, мы в любой момент времени можем готовить релиз, на тестовом сервере только готовые задачи. Вроде бы на этом можно и закончить, но каждый раз для каждой задачи даже разработчику или девопсу трудно разворачивать новое состояние приложения.
Реализация
Для того чтобы погрузиться в техническую реализацию, предлагаю добавить некоторые детали к проекту. Предположим, у нас обычное веб-приложение, например на next.js.
Пришла задача от дизайнера поменять цвет кнопки "Купить" на красный. Разработчик добросовестно выполнил задачу и теперь хочет показать красную кнопку тестировщику.
Прежде чем разбираться, как это сделать, стоит сформулировать критерии выполнения задачи:
QA имеет ссылку на сборку приложения в конкретном состоянии ветки.
Ссылка уникальная и никак не переопределяет дев-сервер
Весь процесс полностью автоматизирован и не требует дополнительных усилий со стороны разработчиков.
Попробуем схематично изобразить решение.
Выглядит просто, как рецепт приготовления макарон. Теперь по шагам помеченным на схеме цифрами в желтом круге.
Разработчик отправляет код в новой ветке в репозиторий. На нашей схеме это "Репозиторий".
Gitlab CI собираем проект в контейнере и отправляет конкретное состояние приложения в реестр без дополнительных усилий разработчика.
Теперь размещаем это в интернете и получаем ссылку на это состояние. Для этого, используем скрипт на python или другом языке. Скрипт запускается по расписанию каждые 7 минут и проверяет не появилось ли новых контейнеров в реестре контейнеров.
Скрипт понимает что появился новый контейнер и размещает на виртуальном сервере. Теперь на сервере запущено приложение в требуемом состояние, но невозможно получить к нему доступ из интернета.
Скрипт меняет конфигурацию nginx. С этого момента, если на локальном компьютере добавить в файл hosts запись ip_address feature6.myproject.com, то получим заветную красную кнопку.
Последняя задача это создать публичную ссылку. Здесь сразу дам допущение, домен делегирован в Cloudfare, который умеет через API менять A-записи. Скрипт на этом шаге — создает A-запись, тем самым получаем заветную ссылку https://feature6.myproject.com и отправляем тестировщику.
Приведу псевдокод, показывающий алгоритм.
var new_containers = list[]; // список контейнеров в реестре
var old_containers = list[]; // список запущенных контейнеров на сервере
// поиск новых контейнеров
var diff = diff(new_containers, old_containers)
for i in diff:
startLocalContainers() // запускаем новый контейнер
patchNginxConfig() // добавляем новую запись в конфигурацию nginx
createNewARecord() // отправляем запрос на API cloudfare для создания A-записи
notify() // Отправляем уведомления в slack или в другой мессенджер
Результат
Мы избавились от бутылочного горлышка в процессе разработки и сделали жизнь разработчиков чуточку лучше. Бонусом, можно подключить уведомления в телеграмме, слеке или бейскемпе или даже прикреплять ссылку автоматически в jira. Эта логика также будет размещена в python-скрипте.
Сегодня мы рассмотрели простой пример, в следующей статье рассмотрим ситуацию, в которой у нас более сложная архитектура приложения с бекендом, фронтом и админкой.
gogatender
Упрощает