Привет, Хабр! Меня зовут Андрей, я SDET-специалист SimbirSoft. В практике CI/CD один из общепринятых стандартов — настройка автоматического запуска автотестов при деплое сервиса на стенды. То есть при запуске сборки мы сразу видим, как пройдут смоук-автотесты, и на основе отчета решаем, передавать сборку дальше QA-команде или дорабатывать. Это упрощает работу команды и позволяет быстрее исправлять ошибки, что критично важно для бизнеса.

Мы разберем автоматический запуск автотестов с использованием Downstream pipelines в GitLab CI на примере проекта с несколькими микросервисами. Они должны триггерить разные группы автотестов, а также имеют разные точки входа, то есть базовые URL. Выглядит это так:

Пайплайн сборки сервисов
Допустим, .gitlab-ci.yml в сборке микросервиса выглядит так:
stages: - build - deploy - test build job: stage: build script: - echo "Build service" deploy job: stage: deploy script: - echo "Deploy service" when: on_success
Сервис при сборке хранит в переменных среды необходимый URL, который далее станет точкой входа для автотестов (например, app.testing.com или app.staging.com). Если этого URL в переменных нет, вы можете добавить разные переменные для разных окружений в настройках этого пайплайна. Сделать это можно в UI GitLab тут Setting -> CI/CD -> Variables, например PARENT_URL для разных Environment scope.

Пойдем по пути использования одного фреймворка с автотестами для этих микросервисов. Мы хотим, чтобы фреймворк жил отдельным пайплайном и мог автономно запускаться без привязки к микросервису.
Для чего нужен автономный запуск? Когда мы написали новый тест-сьюит, и его запуск успешно прошел локально, необходимо проверить, как его прогон пройдет в CI/CD, так как там автотесты могут упасть. Это может быть связано с тем, что под капотом Selenoid автотест может работать иначе, или скорость обработки данных БД чрезмерно высока, и в неё не успевают прилетать сообщения из другого сервиса.
Чтобы автотесты запускались автоматом при деплое сервиса, и при этом сохранялась необходимая автономность, мы будем использовать Downstream pipelines.
Добавляем в .gitlab-ci.yml сборки микросервиса триггер для запуска автотестов:
testing_job: stage: test variables: PARENT_MARK: "smoke_service_a" # Здесь Вы можете указать метку, которую хотите передавать в автозапуск тестов # Для второго микросервиса здесь будет соответственно PARENT_MARK: "smoke_service_b" PARENT_URL: "https://rickandmortyapi.com/api" # Здесь я имитирую передачу сервисом необходимого URL trigger: ansid63/just_ci rules: - if: $CI_COMMIT_BRANCH == "main"
В trigger мы передаем путь к нашему проекту с автотестами в GitLab CI. Поле rules в данном случае устанавливает условие, что автотесты необходимо триггерить при мерже в ветку main.
Пайплайн проекта с автотестами
Переходим к проекту с автотестами. Я сделал небольшой проект с API тестами для проверки работы связки пайплайнов:

В проекте должен быть подключен GitLab Runner. Если вы запускаете проект на gitlab.com, возможно, вам будет достаточно Runner, предлагаемого сервисом GitLab.
В conftest.py я выдергиваю базовый URL для запуска автотестов:
from pytest import fixture def pytest_addoption(parser): parser.addoption( "--url", action="store", default="https://rickandmortyapi.com/api") @fixture() def url(request): return request.config.getoption("--url")
Dockerfile собирает контейнер с автотестами и зависимостями, в автотестах используются библиотеки pytest и requests.
FROM python:3.9.13-slim COPY . . RUN pip3 install -r requirements.txt --no-cache-dir
Папка tests содержит один файл с автотестами.
Давайте разберем пайплайн в .gitlab-ci.yml проекта с автотестами:
stages: - build # Этап сборки контейнера с автотестами и зависимостями - test # Этап запуска автотестов variables: TEST_MARK: value: "smoke_service_a" # Дефолтная mark для pytest TEST_PATH: value: "tests" # Т.к. мы прокидываем --url, pytest очень просит указать путь к местоположению тестов TEST_URL: value: "https://rickandmortyapi.com/api" # Дефолтный URL для pytest AQA_GIT_TAG: v0.1.0 # Тэг для контейнера с автотестами AQA_IMAGE: "${CI_REGISTRY_IMAGE}/autotests:${AQA_GIT_TAG}" # Путь к контейнеру с автотестами .docker-registry: &docker-registry - echo $CI_REGISTRY_PASSWORD | docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY # Шаблон для авторизации в СI registry build_autotest_image: # Данный этап с условием only позволяет нам собирать контейнер только при git push # и избежать постоянной пересборки контейнера при запуске автотестов. stage: build image: gitlab/dind services: - docker:dind before_script: - *docker-registry # Авторизация в СI registry script: - docker build -t ${AQA_IMAGE} . # Собираем контейнер с автотестами и зависимостями - docker push ${AQA_IMAGE} # Пушим контейнер в СI registry only: refs: - pushes # Сборка контейнера происходит только при git push в проекте с автотестами test job 1: # Запуск автотестов при триггере от сборки микросервиса stage: test image: "${AQA_IMAGE}" script: - pytest -m $PARENT_MARK $TEST_PATH --url $PARENT_URL # Запускаем автотесты rules: - if: $CI_PIPELINE_SOURCE == "pipeline" # Согласно данному правилу, этот процесс запускается в случае, если пайплайн триггериться test job 2: # Запуск автотестов при ручном запуске stage: test image: "${AQA_IMAGE}" script: - pytest -m $TEST_MARK $TEST_PATH --url $TEST_URL # Запускаем автотесты rules: - if: $TEST_FROM == "handheld" # Запуск происходит когда в Run Pipeline передаем TEST_FROM == "handheld"
Запуск автотестов
При запуске сборки и деплоя микросервиса у нас автоматически стартуют автотесты:

Если автотесты пройдут с ошибками, билд будет обозначен как failed и подсветится красным. Таким образом команда разработки получит информацию о работоспособности данного конкретного билда системы. В случае, если вы не хотите «фейлить» деплой, а лишь подсветить, что прогон автотестов прошел с падениями, следует добавить allow_failure: true в джобу stage: test.
Если мы хотим запустить автотесты для дефолтных значений в нашем проекте с автотестами, мы переходим во вкладку CI/CD GitLab, нажимаем Run pipeline. В появившемся окне необходимо выбрать branch, а в Variables добавить TEST_FROM со значением handheld, нажать кнопку Run pipeline. В качестве результата вы получите прогон автотестов с меткой smoke_service_a и дефолтным URL https://rickandmortyapi.com/api.
Если вам нужна более гибкая настройка и нужен запуск ветки develop, метки smoke_service_b, файла с автотестами по пути tests/test_api.py::TestRickAndMortyApi и с определенным входным URL, это можно сделать так:

Нажимаете Run pipeline, получаете необходимый вам запуск автотестов. В чем плюс этого подхода — он даёт вам высокую гибкость относительно вариантов запуска.

Вместо вывода
Downstream pipelines предоставляет возможность взаимодействия нескольких проектов, а также возможность передачи необходимых переменных из одного проекта в другой, на основании чего вы можете строить необходимые вам зависимости. Вы добавляете модульности вашей системе и предоставляете готовое решение для автотестов. Для обновления схемы работы автотестов не нужно будет править несколько пайплайнов, а работать только с одним. И это сможет сделать команда автотестирования, которая отвечает за свой пайплайн.
Если вы используете один стенд для запуска автотестов, и прогон автотестов необходим при сборке одного сервиса, можно также использовать Downstream_pipelines для автономности проекта с автотестами.
Спасибо за внимание!
Полезные материалы для разработчиков мы также публикуем в наших соцсетях – ВКонтакте и Telegram.
ссылка на оригинал статьи https://habr.com/ru/company/simbirsoft/blog/715028/
Добавить комментарий