Pull to refresh
0
Kolesa Group
Строим классифайды в Центральной Азии

Newman и Continuous Integration на примере Atlassian Bamboo. Изобретение велосипеда

Reading time7 min
Views10K


Введение


В недавней статье наш боевой товарищ actopolus рассказал о том, как мы научились применять Postman для реализации функционального тестирования нашего API проекта. Научившись писать функциональные тесты, и написав их порядка полутора сотен, мы решили, что настало то самое время — время прикрутить эти тесты к нашим CI-сборочкам.


Вообще, изначально процесс интеграции Postman-тестов в сборки можно было разбить на 3 простых этапа:


  1. Формирование production-ready коллекции тестов для Postman
  2. Подготовка docker-образа среды для запуска тестов
  3. Написание тасков для того, чтобы собрать всё воедино и запускать на агентах

Однако, нами не был учтён один очень важный нюанс — у нас не было инструмента для измерения покрытия нашего кода Postman-тестами. Без информации о том, насколько хорошо мы покрываем тестами код, нам было сложно понять где мы находимся сейчас и к чему нам нужно стремиться. Следовательно, план был дополнен ещё одним пунктом:


  1. Написание тасков для того, чтобы собрать всё воедино и запускать на агентах.


1. Коллекция тестов


Итак, приступим к самому процессу. С первым пунктом наша команда справилась героически быстро, тем более, что production-ready версия не так уж сильно отличалась от dev, в том смысле, что качество тестов, которое мы писали в Postman для «пробы пера» оказалось достаточно высоким. О том, как правильно писать Postman-тесты и что к чему, уже рассказывал actopolus в своей статье Введение в Postman. Каким же образом запустить Postman из консоли? Ответ прост — никак. Но, к счастью, есть специальная консольная утилита, которая умеет почти всё тоже самое, что и Postman, и имя ей… Newman!
Именно благодаря Newman мы и будем проводить интеграцию Postman-тестов в CI.

2. Docker


Тем временем я принялся за докер образ. Сначала был собран собственный образ на базе alpine, на котором были проведены первичные запуски. После чего я обнаружил, что в недрах докер-хаба таки есть уже готовый образ с Newman, собранный на все том же alpine, но более легковесный. Казалось, задача свелась лишь к тому, чтобы слить уже существующий образ с докер-хаба в наш локальный хаб, однако, выяснилось, что он не подходит нам в чистом виде из-за несоответствия стандартам, принятым внутри компании. Поэтому пришлось всё же собрать свой образ. Для этого прежде всего мы сменили базовый образ на наш alpine который используется у нас во всех образах подобного рода. Следующим шагом мы выпилили все неиспользуемые компоненты и сменили точку входа таким образом, чтобы нам было достаточно передать образу только параметры для newman, не передавая всю строку запуска. Именно так и получился образ, который нас устроил по всем параметрам и попал в наш докер-хаб.

3. Кочергатор для измерения покрытия


После неудачных попыток родить ежа прикрутить к newman-тестам библиотеку c3 от codeception, я решил, что пожалуй быстрее будет изобрести велосипед написать свою библиотеку для сбора покрытия тестов newman (согласен, звучит очень по-профански).


Почему я решил изобрести велосипед:


  1. Простота использования. Если вам необходимо родить пару ежей против шерсти для того, чтобы подключить измерение покрытия кода тестами в вашем приложении, вероятнее всего с реализацией что-то не так. Наша библиотека подключается 1ой строкой.
  2. Так как у нас не один, а множество проектов, мы можем учесть все их особенности в библиотеке, что в последствие позволит легко её использовать.
  3. Мы сами гарантируем поддержку работоспособности библиотеки. Она не исчезнет никуда через полгода и мы всегда сможем перенести её на новую версию php.

«Чего тянуть кота за яйца?» — подумал я и решил начать писать кочергатор для измерения покрытия, тем более, что большая часть работы (пожалуй все 90%) для такой цели уже реализована в библиотеке php-code-coverage, использующей в своей основе xDebug. Осталось лишь немного переложить её на свой лад.


Итак, наш кочергатор будет состоять из 2х частей. Первая будет отвечать за сбор и подготовку отчетов о запущенных во время прохождения теста файлах и строках, вторая будет представлять из себя CLI-приложение, которое будет собирать все отчеты воедино и форматировать в указанный формат.



Как это работает в библиотеке SebastianBerghmann?


По сути, php-codecoverage это надстройка над парой драйверов на выбор (phpdbg, xDebug). Суть проста, вы инициализируете скрипт на сбор информации о выполняемых (и не выполняемых) строках, и на выходе получаете массив с этими данными. Библиотека php-codecoverage создана для того, чтобы из этих массивов делать сексуальные отчеты в форматах xml, html, json и text. Она также разделена на 2 части, и также одна часть занимается сбором информации, а вторая форматированием.



Что делает наш велосипед?


  • Подключается одной строкой
    $coverage = new Coverage();
  • Имеет дефолтную конфигурацию
  • Начинает слушать тогда и только тогда, когда встречает в заголовке запроса определенный флаг.
  • Складывает все отчеты туда, куда мы ему скажем.
  • CLI — умеет не только собирать отчеты, но и чистить за собой.

Для того, чтобы всё это богатство заработало, нам пришлось добавить в наши тесты заголовок-маркер.

Выглядеть это стало вот так:




«Скомпилированные» отчёты позволяют посмотреть в каком тесте запускаются те или иные строки кода и выглядят следующим образом:


Так выглядит экран с покрытием кода




Так выглядит покрытие кода по папкам

Отчёты генерируются утилитой, которая входит в состав пакета php-code-coverage.
Если уважаемому читателю будет интересно, то мы расскажем про то, как работает этот кочергатор в отдельной небольшой статье.

Итак с пунктом 3 мы тоже разобрались. Остался не менее интересный пункт… 4ый

Пункт 4ый, драматический


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



1. Итак, сначала кодовая база сливается из GIT-репозитория на агент BAMBOO и далее на нем происходит сборка проекта.


В нашем случае собирается composer и происходит обработка файлов конфигурации под Development окружение. Именно на этом этапе мы подменяем в наших тестах значение заголовка PHPNEMWMAN_OFF на PHPNEWMAN_ON (это потому, что билд-план призван замерять покрытие, однако не стоит это делать в билд-плане, который своей целью ставит именно сборку проекта, т.к. измерение покрытия значительно замедляет процесс сборки).


sed -i -e "s/Phpnewman-Off/Phpnewman-On/" ./code/newman/collection.json

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


3. После того как собранный проект благополучно слит в артефактори, следующий таск также благополучно его оттуда сливает и выгружает на тестовый бэкенд.


4. Следующий таск также сливает проект из артефактори и запускает на нем newman-тесты. Нужно сразу отметить, что ходить эти тесты будут не на localhost bamboo-агента, а на тестовый бэкенд, куда мы вылили проект шагом ранее. Тесты запускаются в докер-контейнере.


Запустить тесты в докер-контейнере можно достаточно просто:


docker pull docker-hub-utils.kolesa:5000/build/nodejs/newman:latest
#Скачиваем образ из репозитория

docker run \ #запускаем контейнер
--rm \ #удаляем контейнер сразу после остановки
--volume $(pwd):/code \ #монтируем корень агента в папку /code в контейнере
--volume /etc/passwd:/etc/passwd:ro \ #монтируем passwd
--volume /etc/group:/etc/group:ro  \#монтируем group
--user $(id -u):$(id -g) \ #устанавливаем пользователя и группу, от имени которой действуем в контейнере
--interactive \ #режим запуска - интерактивный
docker-hub-utils.kolesa-team.org:5000/build/nodejs/newman:latest \
    run collection.json --folder Tests -r junit,html --reporter-junit-export _out/newman-report.xml --reporter-html-export _out/newman-report.html -e _envs/qa.json -x

Строку запуска newman разберем отдельно:


run collection.json #Запустить тесты из файла collection.json
 --folder Tests #Директория в json-объекте(collection.json) где лежат тесты
 -r junit,html #Отчеты о прохождении (не покрытие!) тестов готовим в 2х форматах
 --reporter-junit-export _out/newman-report.xml #указываем явно, куда сложить отчет
 --reporter-html-export _out/newman-report.html #указываем явно, куда сложить отчет
 -e _envs/qa.json  #указываем json с переменными окружения
 -x #возвращать exit-code основываясь на результате прохождения тестов

После этих манипуляций на нашем тестовом бэкенде сформируется коллекция COV-отчётов, совпадающая численно с количеством запросов к бэкенду.

Осталось всего-ничего собрать все эти cov-отчеты в один большой жирный отчет.
Для простоты понимания в скрипте ниже будем использовать `SCP`.

Итак, сбор отчетов происходит следующим образом:


BRANCH_NAME=$(echo "${bamboo.currentBranch}" | sed 's|/|-|g' | sed 's@\(.*\)@\L\1@') 
#кладём имя ветки из бамбу в переменную окружения

echo "BRANCH NAME IS $BRANCH_NAME" 
#пишем имя ветки в логи

ssh www-data@testing.backend.dev "php /srv/www/$BRANCH_NAME/vendor/wallend/newman-php-coverager/phpnewman --collect-reports merge /srv/www/$BRANCH_NAME/phpnewman --clover /srv/www/$BRANCH_NAME/newman/_output/clover.xml --html /srv/www/$BRANCH_NAME/newman/_output/html"
#запускаем сборку отчётов на удалённом бэкенде

scp www-data@testing.backend.dev:/srv/www/$BRANCH_NAME/newman/_output/clover.xml ./clover.xml
scp -r www-data@testing.backend.dev:/srv/www/$BRANCH_NAME/newman/_output/html ./
# сливаем готовые отчёты на агент

ssh www-data@testing.backend.dev "rm -r /srv/www/$BRANCH_NAME/newman/_output/html && rm /srv/www/$BRANCH_NAME/phpnewman/* && rm /srv/www/$BRANCH_NAME/newman/_output/clover.xml"
#чистим за собой на бэкенде

Для того, чтобы в сборке были доступны ваши отчёты, необходимо расшарить артефакты с этими отчётами:



далее мы можем использовать эти артефакты для автоматического парсинга и дальнейшей визуализации покрытия кода в нашей сборочке. Для этого достаточно поставить галочку и указать файл с xml-отчётом покрытия.



На выходе получаем вот такую красоту (В данном случае аналогичные операции проделаны для отчетов UNIT-тестов).

Важно!


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

Заключение


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


Факт первый. Нет ничего сложного в том чтобы прикрутить к Continuous Intgration новый, понравившийся вам инструмент. Было бы желание.


Факт второй. Если чего-то в инструменте нет из коробки, то совсем не обязательно, что доработать это самому окажется сложным и муторным занятием. Иногда, если разобраться, то всё решается в пару-тройку десятков строк кода. Добавьте сюда огромный профит от использования инструмента, когда всё заработает. Ну и плюс ко всему это ещё один повод прокачать свои навыки.


Факт третий. Никто не утверждает что newman это панацея от всех бед, и что он лучший в качестве инструмента функционального тестирования. Однако, мы попробовали — и нам понравилось, особенно после того как он был прикручен к CI!


Ну и, конечно же, мы будем рады, если наша библиотека принесет вам пользу. А если у вас возникнет необходимость ее доработать – feel free to contribute!

Tags:
Hubs:
Total votes 13: ↑12 and ↓1+11
Comments14

Articles

Information

Website
job.kolesa.kz
Registered
Founded
Employees
201–500 employees
Location
Казахстан
Representative
Anel Kerimbekova