Хабрахабр

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! Ну и, конечно же, мы будем рады, если наша библиотека принесет вам пользу.

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

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

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

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

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