Блог
Теория и инструменты тестирования

CI/CD простыми словами: pipeline, stage, job

CI/CD обязательно спрашивают на собеседовании QA уровня Middle, и без понимания GitFlow и процесса деплоя невозможно правильно тестировать в реальной команде: непонятно, на какой ветке смотреть баг, куда деплоить фикс и почему функциональность внезапно «пропала» после релиза. Тема опирается на несколько связанных понятий — GitFlow, тестовые окружения, автоматические проверки кода — и разобраться в ней стоит именно как в целостном процессе, а не как в наборе отдельных терминов для заучивания.

Что такое DevOps и зачем он появился

DevOps — сокращение от Development + Operations, то есть «поддержка разработки». Раньше, во времена водопадной методологии, деплой на продакшн занимал недели, и администраторы с разработчиками взаимодействовали спокойно, без острой необходимости в отдельной связующей роли. Ситуация изменилась с приходом Agile: скорость доставки функций выросла, и понадобился человек, который убирает трение между этапами разработки, доставки и поддержки — так появилась роль DevOps-инженера.
DevOps не существует сам по себе в отрыве от команды и сложных процессов — он нужен там, где большой объём работы, ежедневные релизы и сложная инфраструктура. DevOps-инженер — разносторонний специалист: разбирается в разработке, администрировании, сетях, методологиях и способах автоматизации. При этом не на каждом проекте есть отдельный DevOps: если объём работы небольшой или бюджета на отдельного специалиста нет, задачи настройки CI/CD и деплоя берут на себя сами разработчики.

GitFlow и тестирование: пять этапов

В GitFlow тестировщик встречается с кодом на нескольких этапах, и на каждом — своя роль. Feature-ветка — маленькая временная ветка под одну задачу, тестирование здесь происходит редко: разработчик может передать ветку QA ещё до Merge Request. Develop — основная ветка разработки, и именно на ней тестирование происходит чаще всего: после того как код прошёл код-ревью и был слит в develop, QA проверяет задачу на develop-окружении.
Дальше наступает этап регрессии — и здесь возникает практическая проблема: полная регрессия занимает 2–4 дня, а за это время разработчики продолжают мержить новые задачи в develop, и тестирование обесценивается, потому что появляется код, качество которого ещё никто не проверял. Решает это Release branch: в момент готовности к релизу develop клонируется в отдельную ветку release/2.0, и пока QA спокойно тестирует регрессию именно в ней, разработчики продолжают мержить новые задачи уже в develop, готовя следующий релиз. Если на регрессии находят баг, разработчик чинит его прямо в release-ветке, а не в develop, — фикс тестируется отдельно, и затем проводится сокращённая или полная повторная регрессия в зависимости от критичности изменений.
После успешной регрессии release-ветка мержится в main — это и есть момент релиза, когда изменения становятся видны пользователям. Финальный этап — smoke-тестирование на проде: вручную проверяется ключевой функционал, а заодно отслеживаются метрики и логи. Например, если обычно фиксируется 25 ошибок 500 в сутки, а после релиза их стало 300 — это повод для тревоги немедленно, а не после следующего спринта.

Hotfix и Rollback: два сценария для критичных багов

Если баг на регрессии оказался критичным и быстро его не пофиксить, разумнее сделать Rollback — откат до последнего стабильного релиза, чтобы пользователи получили рабочий продукт, а не сломанный, пусть и с опозданием по срокам. Проблемный функционал чинят уже в следующем релизе.
Другой сценарий — если критичный баг обнаружен уже на проде и его можно быстро исправить. Тогда используется Hotfix: важная деталь в том, что ветка хотфикса ответвляется от main, а не от develop, и весь обычный цикл с develop и release-веткой при этом обходится. Фикс делается за считаные часы, мержится сразу в main, и снова проводится smoke-тестирование на проде. После хотфикса изменения обязательно нужно слить обратно в develop — иначе develop начнёт отставать от main, и в следующем релизе может случайно потеряться уже исправленный баг.

Что значит «тестировать на ветке»

Ветка — это состояние кода в конкретный момент времени, а пользователи взаимодействуют с конкретным сайтом на конкретном домене, а не с кодом напрямую. У проекта обычно несколько окружений: Production — основной домен для реальных пользователей, Stage (или Pre-prod) — для регрессии на релизной ветке, и одно или несколько Dev-окружений — для develop или отдельных feature-веток. «Тестировать на ветке» на практике означает задеплоить код этой ветки на конкретное окружение и открыть соответствующий домен в браузере — сам процесс доставки кода на окружение и есть Continuous Delivery.

Continuous Integration и Continuous Delivery/Deployment

CI, непрерывная интеграция, — практика, при которой изменения в коде автоматически собираются, тестируются и интегрируются в целевую ветку. В отличие от код-ревью, где разработчики вручную читают код и находят логические проблемы, CI работает через автоматические инструменты — линтеры, статические анализаторы, юнит-тесты, метрики покрытия — и находит опечатки, нарушения стиля, неверные отступы. Если автоматических проверок достаточно для оценки качества, Merge Request может автомерджиться в целевую ветку без ручного код-ревью вовсе.
CD, непрерывная доставка или развёртывание, — продолжение CI, которое автоматически разворачивает уже собранный и проверенный код на нужном окружении: собирает проект, настраивает переменные окружения, разворачивает базу данных, поднимает серверы, и в итоге код попадает на Dev, Stage или Prod. Здесь важно различать два похожих понятия: Continuous Delivery подразумевает, что весь процесс автоматизирован вплоть до последнего шага, а сама выкладка на прод происходит по нажатию кнопки вручную. Continuous Deployment идёт дальше — весь процесс, включая финальное развёртывание на проде, происходит полностью автоматически, без участия человека. Continuous Delivery используется значительно чаще: риски ниже, а ручная кнопка перед проды — простой и надёжный предохранитель.

Pipeline, Stage, Job: как устроен процесс на практике

Хорошая метафора для Pipeline — трубопровод с фильтрами: код проходит через них по очереди, как вода — через фильтр крупных частиц, потом мелких, потом угольный, и на выходе получается «чистый», готовый к продакшну код. Внутри Pipeline — несколько Stage (стадий), а внутри каждой стадии — несколько Job (задач). Job — по сути автоматизированная последовательность команд в консоли, тот же набор команд, что можно ввести вручную в терминале, только выполняется он автоматически, а результат виден в интерфейсе GitLab или Jenkins как вывод в консоль. Например, стадия Tests на реальном проекте может состоять из нескольких job: автотесты, линтер, проверка спецификаций — и стадия считается пройденной только тогда, когда успешны все job внутри неё.
Основные инструменты для CI/CD — GitLab CI/CD, встроенный прямо в GitLab и тесно интегрированный с репозиториями, и Jenkins — отдельный, независимый от репозитория инструмент с открытым исходным кодом. Комбинации возможны любые: репозиторий на GitLab с его же встроенным CI/CD, или репозиторий на GitLab с CI на GitLab и деплоем через Jenkins. Конфигурация Pipeline в GitLab хранится в файле .gitlab-ci.yml в корне репозитория — там перечислены переменные, стадии, job внутри каждой стадии и скрипты, которые они выполняют. Результатом работы job может быть артефакт — файл, который job оставляет после себя: лог, отчёт о покрытии тестами, собранный билд проекта, доступный для скачивания в интерфейсе.
Отдельная специфика возникает на проектах с микросервисной архитектурой, где у каждого сервиса свой репозиторий и свой собственный pipeline. Тестировщику, который раньше работал только с монолитом, здесь легко допустить ошибку: если разработчик внёс изменения сразу в два сервиса, нужно задеплоить develop-ветку в pipeline каждого из них — забытый сервис приводит к тому, что функциональность просто не заработает, и разбираться, почему, придётся уже во время тестирования. Важное правило — на одном окружении в один момент времени может быть развёрнута только одна ветка одного сервиса, при этом у разных сервисов на одном и том же окружении ветки вполне могут различаться.
Собрать всю картину CI/CD в голове по одному описанию сложно — она складывается, когда своими руками проходишь по pipeline, смотришь консоль выполнения job и видишь, как код одной и той же ветки оказывается сначала на Dev, а после регрессии — на проде. На курсе «Инженер по ручному тестированию» GitLab CI/CD и Jenkins разбираются в Спринте 10 на практике: ученики настраивают собственный .gitlab-ci.yml, деплоят проект через Jenkins на разные окружения и разбирают с ментором именно те ситуации, которые чаще всего вызывают путаницу на реальном проекте.
-------

Полезные ссылки школы

Сайт Quality Academy:
/main
Telegram-канал:
https://t.me/quality_academy
YouTube-канал:
https://www.youtube.com/@quality_academy
ВКонтакте:
https://vk.com/quality_academy
Канал отзывов учеников (58+ отзывов):
https://t.me/quality_academy_reviews
Задать вопрос менеджеру:
https://t.me/quality_academy_bot
Тест «Подойдёт ли вам тестирование»:
https://quiz.quality-academy.ru
5000+ вопросов с собесов тестировщика — бот-тренажёр:
https://t.me/quality_academy_interview_bot
3 практические задачи и дорожная карта:
https://t.me/quality_academy_tasks_bot
Бесплатные тренажёры — SQL Arena, Playwright Arena, Python Arena:
SQL Arena · Playwright Arena · Python Arena