Хабрахабр

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

Введение

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

Вообще, изначально процесс интеграции 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.

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

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

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

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

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

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

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

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

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

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

Если уважаемому читателю будет интересно, то мы расскажем про то, как работает этот кочергатор в отдельной небольшой статье.

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

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

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

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

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

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

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

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

Следующий таск также сливает проект из артефактори и запускает на нем newman-тесты. 4. Тесты запускаются в докер-контейнере. Нужно сразу отметить, что ходить эти тесты будут не на 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 "$" | 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! Ну и, конечно же, мы будем рады, если наша библиотека принесет вам пользу.

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

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

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

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

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