Разработчик пишет: «поправил, у меня работает». Вы открываете стенд — не работает. Полчаса уходит на выяснение, что на стенде позавчерашняя сборка, а правка живёт только на его ноутбуке. Назавтра то же с другой задачей: кто-то забыл залить, кто-то собрал не ту ветку.
Дисциплиной это не лечится — лечится машиной. Отдельный сервер берёт каждую правку из общей ветки и сам собирает из неё продукт на чистой машине: одинаково для всех, без «а у меня». Такая автоматическая сборка на каждую правку называется непрерывной интеграцией (continuous integration, CI), а вместе со следующим шагом — автоматической доставкой собранного до выпуска — CI/CD.
Шаги идут по очереди, и каждый решает, поедет ли сборка дальше. Дымовой набор нашёл красную проверку — выпуск перечёркнут, а отчёт уже говорит, какая именно проверка упала и что сервис ответил вместо ожидаемого.
Конвейер: пять шагов и ворота между ними
Собрать проект — ещё не значит проверить его, поэтому конвейер почти никогда не бывает одним действием. Список шагов лежит файлом в том же репозитории, что и код, и правится так же, как код.
stages:
- build # из исходников — то, что можно запустить
- unit # модульные тесты разработчиков, минуты
- deploy-staging # поставить собранное на стенд
- smoke # автопроверки главного пути
- report # что прошло, что упало, где смотреть
Шаг здесь — ещё и ворота. Упали модульные тесты — развёртывания не будет: ставить на стенд заведомо сломанное незачем. Не поднялся стенд — дымовой набор не запустится, иначе вы получите двенадцать красных отметок по одной причине. Это тот же критерий входа, что и в тест-плане, только исполняет его машина.
Главная польза именно в этом: сломанное видно через пять минут после правки, пока автор помнит, что делал, — а не через неделю, когда на разбор уходит день.
Где в конвейере ваши автотесты
Автотесты, которые запускают руками и когда вспомнят, перестают гонять на третьей неделе. Польза появляется, когда прогон привязан к событию, а наборы поделены по времени. Быстрое и надёжное — дымовой набор, десяток проверок API на главный путь — вешают на каждую правку: пять минут команда подождёт. Полный регресс на сорок минут никто ждать не станет, его пускают ночью по расписанию, а утром разбирают отчёт. Тесты интерфейса — отдельным набором и реже всех: самые медленные и капризные.
Ручные проверки встают в тот же ряд: их начинают на зелёном конвейере, а не когда «сборка вроде приехала».
Тест не должен зависеть от соседа
Локально набор зелёный, в конвейере — красный через раз, и всегда разные тесты. Причина почти всегда одна: тесты договорились между собой, а машина об этом не знала — она запускает их в своём порядке и часто в несколько потоков сразу. Тест «вход в кабинет», который рассчитывает, что покупателя qa@shop.ru уже создал тест «регистрация», покраснеет просто от перестановки. Хуже другое: два потока начнут регистрировать одного и того же покупателя, второй получит «адрес занят» — и упадёт тест, в котором нет ни одного дефекта.
Отсюда три правила — они не про CI, а про сами тесты: каждый тест сам готовит себе данные и убирает за собой; значения, которые должны быть уникальными, делают уникальными (qa+1726212000@shop.ru); ждут не время, а состояние — sleep 5 на загруженном стенде не спасает, а тормозит прогон.
Артефакт: что остаётся от сборки
«На каком стенде какая версия?» — вопрос, с которого начинается половина разборов. Ответ даёт артефакт: файл или образ, который получился на шаге сборки и который можно запустить как есть. У него есть номер сборки и правка, из которой он собран, — та самая пара, что идёт в баг-репорт.
Правило тут одно: артефакт собирают один раз и дальше только переставляют. Пересоберёте под каждый стенд заново — на продукт поедет не то, что вы проверяли, и разница вылезет там, где её не ждут.
Второй смысл слова — артефакты прогона: отчёт, логи сервиса, скриншоты, видео, запросы и ответы. Они хранятся рядом с прогоном, и это не мелочь: стенд к утру перезальют, а отчёт недельной давности останется единственным следом падения.
Как разбирают красный прогон
Порядок разбора экономит часы. Сначала имя упавшей проверки и сообщение — что ждали и что пришло. Потом шаг, на котором упало: модульные тесты и дымовой набор ломаются по разным причинам. Дальше артефакты — лог сервиса, скриншот, тело ответа. И только потом руки: повторить тот же шаг на той же сборке.
Исходов три, и путать их дорого. Дефект в продукте — заводим отчёт со ссылкой на прогон. Тест устарел: требование поменялось, ответ стал другим по делу — чинить тест, а не продукт. Обстановка: стенд не поднялся, кончилось место на диске, отвалилась соседняя система — продукт цел, но красное всё равно разбирают, иначе оно станет фоном.
Нестабильный тест: почему нельзя просто перезапустить
Проверка упала, нажали «повторить» — зелёная. Тот же код, тот же стенд, разный результат: такой тест называют нестабильным. Узнают его по истории прогонов: падает на неизменившемся коде, скажем семь раз из ста.
Перезапуск делает две плохие вещи. Он прячет настоящий дефект: гонка в продукте выглядит точно так же — «обычно работает, иногда нет», и у пользователя проявится тем же способом. И он ломает отношение к красному: команда привыкает жать «повторить» не глядя и однажды перезапускает настоящий отказ.
Поэтому нестабильный тест лечат: помечают, заводят задачу с числом падений, выводят из блокирующего набора в карантин — чтобы не держал выпуск, но и не пропал из виду, — и чинят причину: ожидание времени, общие данные, зависимость от порядка. Молча выключить проверку — то же, что удалить её, только без записи в истории.
Доставка и развёртывание
Конвейер зелёный — и дальше вопрос, кто нажимает кнопку выпуска. Две буквы CD расшифровывают двумя способами, и разница ровно в этой кнопке: continuous delivery — конвейер доводит артефакт до состояния «можно выпускать», а выпускает человек; continuous deployment — кнопки нет, зелёный конвейер уезжает на продукт сам. Для проверок это вопрос о последней точке, где ещё можно сказать «не выпускаем»: во втором случае её роль играют автотесты.
Коротко
- CI — автоматическая сборка и проверка каждой правки на чистой машине: доказательство работоспособности — прогон, а не чужой ноутбук.
- Конвейер — цепочка шагов со створками: сборка, модульные тесты, стенд, дымовой набор, отчёт; красный шаг дальше не пускает.
- Быстрые проверки вешают на каждую правку, длинный регресс — на ночь; ручные начинают на зелёном конвейере.
- Тест обязан готовить себе данные и не зависеть от порядка: конвейер запускает проверки как ему удобно, часто параллельно.
- Артефакт собирают один раз и переставляют по стендам; артефакты прогона — отчёт, логи, скриншоты — переживают перезалив стенда.
- Нестабильный тест не перезапускают: помечают, выводят в карантин и чинят причину, иначе команда перестаёт верить красному.
Что почитать дальше
- Как устроена автоматизация — когда автотесты окупаются и какие кейсы вообще стоит автоматизировать.
- Автотесты API на Python — как выглядят изнутри те самые проверки, которые гоняет конвейер.
- Отчёт о тестировании и метрики — что говорит команде число «18 из 20» и чего оно не говорит.
- Тест-план и тест-сьюты — откуда берутся критерий входа и наборы, которые конвейер запускает.