Разделы портала

Онлайн-тренинги

.
Инфраструктура + тестирование = любовь
20.04.2022 00:00

Автор: Максим Буранбаев, Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript

Инфраструктура тестирования обсуждается реже чем проблемы программирования или шестизначные зарплаты. Дьявол кроется в деталях, а если точнее, то дьявол сидит в процессах внутри команды. В небольших командах процессы устраиваются сами собой без обсуждения. Продуктивность команды снижается по мере роста команды и в условиях игнорирования процессов.  Статью будет полезно прочитать, если команда испытывает следующие трудности:

  • тестирование становится бутылочным горлышком и замедляет работу;

  • в продукт баги проникают чаще чем хотелось. 


Процесс

Классический процесс в микрокоманде на ранних этапах выглядит следующим образом:


Шаги с первого по четвертый не стоят обсуждения, сразу перейдем к шагу номер пять. Чаще в микрокомандах тестировщик не разворачивает проект локально и не переключается на нужную ветку. Тестирование проходит на тестовом сервере, который соответствует ветке develop.

Процесс выстроен логично, но давайте пофантазируем насчет ожидаемых проблем. Если задача сложная и цикл тестирования и внесения изменений продолжительный, то такая задача тормозит остальные задачи и разработчики либо сделает релиз гораздо позже, либо будут мерджить небольшие задачи напрямую в ветку master.

Получается нечто вроде конвейера, если на ленте (dev-server) застряла Feature 6, это блокирует конвейер и предприятие останавливается. Согласно теории ограничений, это классическое бутылочное горлышко. Выпуск релиза будет отложен ровно на столько, сколько требуется на исправление проблем в Feature 6. Если однажды Feature 6 попала в ветку develop, остальные задачи (Feature 4, Feature 5) будут ожидать исправления ошибок в Feature 6. При таком подходе, трудно делать релизы вовремя, будут задачи, которые блокируют релиз.

Если внимательно посмотреть на схему, очевидное решение – сливать в ветку develop только готовые задачи, для этого код должен быть протестирован. Для тестировщика или менеджера затруднительно разворачивать локально проект и переключаться с одной ветки на другую. Следовательно, для каждой разрабатываемой задачи необходим собственный сервер с публичным доступом. Попробуем!  

Теперь, разработчик для каждой задачи или состояния проекта имеет свой собственный домен и может отправить его тестировщику. При этом, если в коде есть какие-то проблемы, это не заблокирует релиз, так как проблемный код еще не попал в develop ветку. Значит, мы в любой момент времени можем готовить релиз, на тестовом сервере только готовые задачи. Вроде бы на этом можно и закончить, но каждый раз для каждой задачи даже разработчику или девопсу трудно разворачивать новое состояние приложения. 

Реализация

Для того чтобы погрузиться в техническую реализацию, предлагаю добавить некоторые детали к проекту. Предположим, у нас обычное веб-приложение, например на next.js.

Пришла задача от дизайнера поменять цвет кнопки "Купить" на красный. Разработчик добросовестно выполнил задачу и теперь хочет показать красную кнопку тестировщику.

Прежде чем разбираться, как это сделать, стоит сформулировать критерии выполнения задачи:

  1. QA имеет ссылку на сборку приложения в конкретном состоянии ветки. 

  2. Ссылка уникальная и никак не переопределяет дев-сервер

  3. Весь процесс полностью автоматизирован и не требует дополнительных усилий со стороны разработчиков.

Попробуем схематично изобразить решение. 

Выглядит просто, как рецепт приготовления макарон. Теперь по шагам помеченным на схеме цифрами в желтом круге.

  1. Разработчик отправляет код в новой ветке в репозиторий. На нашей схеме это "Репозиторий".

  2. Gitlab CI собираем проект в контейнере и отправляет конкретное состояние приложения в реестр без дополнительных усилий разработчика.

  3.  Теперь размещаем это в интернете и получаем ссылку на это состояние. Для этого, используем скрипт на python или другом языке. Скрипт запускается по расписанию каждые 7 минут и проверяет не появилось ли новых контейнеров в реестре контейнеров.  

  4. Скрипт понимает что появился новый контейнер и размещает на виртуальном сервере. Теперь на сервере запущено приложение в требуемом состояние, но невозможно получить к нему доступ из интернета.

  5. Скрипт меняет конфигурацию nginx. С этого момента, если на локальном компьютере добавить в файл hosts запись ip_address feature6.myproject.com, то получим заветную красную кнопку.

  6. Последняя задача это создать публичную ссылку. Здесь сразу дам допущение, домен делегирован в 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-скрипте. 

Сегодня мы рассмотрели простой пример, в следующей статье рассмотрим ситуацию, в которой у нас более сложная архитектура приложения с бекендом, фронтом и админкой.

Обсудить в форуме