CI integration for autotests

Как встраивать автотесты в CI так, чтобы они ускоряли релизный цикл, а не становились формальной и шумной преградой.

Обновлено:

Содержание

Интеграция автотестов в CI превращает отдельные проверки в регулярный механизм обратной связи. Изменение кода запускает воспроизводимый набор, результат привязан к конкретной сборке, а команда получает достаточно данных для решения. Цель — быстро понять риск изменения и устранить причину отказа.

Просто добавить команду test в pipeline недостаточно. Нужны готовое окружение, независимые данные, понятные правила блокировки и доступные артефакты. Иначе CI автоматизирует ожидание и повторные прогоны, а доверие к результату остаётся низким.

Разделите набор по назначению

Быстрые узкие проверки полезны на каждом запросе изменений. Сервисные проверки подтверждают контракты и важные бизнес-правила. Небольшой UI smoke может контролировать главные пользовательские цепочки. Дорогую матрицу браузеров или устройств запускают по согласованным триггерам.

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

Воспроизводимое окружение

Устанавливайте зависимости из сохранённого lock-файла, фиксируйте runtime и версию приложения. Для браузерных инструментов нужны соответствующие браузеры и системные библиотеки. Кэш ускоряет подготовку, но не должен незаметно подменять версию или скрывать отсутствующую зависимость.

Сервис проверяют на готовность, а не ждут произвольные тридцать секунд. Readiness должна означать доступность необходимых для сценария частей: открытый порт сам по себе не подтверждает завершение миграций или готовность очереди. Ошибка подготовки должна быть отличима от продуктового assertion.

Минимальный пример GitHub Actions

Предположим, в репозитории уже настроен Playwright Test, сохранены package-lock.json и .nvmrc с поддерживаемой версией Node, а тесты используют локальную форму через page.setContent. Собственный сервер приложения для этого примера не нужен. Сохраните workflow как .github/workflows/tests.yml.

yaml
name: Browser checks
on:
  pull_request:
  workflow_dispatch:
permissions:
  contents: read
jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version-file: .nvmrc
          cache: npm
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test --reporter=html
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 7

Ожидается запуск на pull request или вручную, отдельный результат job и HTML-артефакт, если отчёт успел создаться. Неверное assertion должно сделать job неуспешным, а шаг загрузки отчёта всё равно выполнится. Указанный таймаут является учебным бюджетом, который нужно подобрать под набор.

Подключение настоящего приложения

Для реального стенда используйте контролируемый запуск сервиса либо выделенный preview нужной сборки. Адрес передают явно; тест должен знать, какую версию проверяет. Если backend и frontend развёрнуты отдельно, сохраняйте обе версии, иначе зелёный результат может относиться к несовместимой комбинации.

Создайте отдельного пользователя и заказ на прогон. Проверьте smoke: вход, оформление учебного заказа и чтение результата. Ожидайте конкретный статус и данные без реального списания денег. Затем намеренно нарушьте ожидание в учебной ветке и убедитесь, что pipeline действительно блокирует неверный результат.

Секреты и права

Credentials хранят в механизме секретов CI и выдают только нужным job. Не печатайте токены в командной строке, отчётах и сетевых артефактах. Маскирование стандартного лога не гарантирует очистку screenshot, JSON-вложений или trace.

Отдельно продумайте внешние pull requests: недоверенный код не должен получать привилегированные credentials. Не меняйте триггер на более привилегированный только ради прохождения тестов. Для такого вклада полезен набор без секретов и отдельный доверенный процесс интеграционного запуска.

Параллельность и ресурсы

Распределение по workers или shards помогает, когда данные и ресурсы независимы. Один общий аккаунт, фиксированный порт или глобальная очистка могут создать гонки. Сначала подтвердите независимость, затем увеличивайте параллельность и измеряйте выигрыш.

Наблюдайте не только длительность тестов, но и очередь агентов, установку зависимостей, запуск приложения и расследование. Иногда уменьшение тяжёлой подготовки даёт больший эффект, чем удвоение числа workers. Изменение ресурса CI должно сохранять сопоставимость результатов.

Блокирующие проверки и исключения

Для required check нужен понятный владелец и правило реакции. Продуктовый отказ требует исправления или осознанного решения о риске. Инфраструктурный отказ требует восстановления окружения. Статус skipped не должен автоматически означать, что критическая проверка выполнена.

Временное исключение оформляют с причиной, сроком и компенсирующей проверкой. Если нестабильный сценарий помещён в карантин, его результат остаётся виден отдельно. Молчаливый continue-on-error для всего набора превращает тесты в необязательный лог.

Проверьте и отрицательный путь самой интеграции: неверная зависимость, недоступный сервис и проваленное assertion должны оставлять разные полезные следы. Отдельно убедитесь, что переименование workflow или job не оставило правило required check ожидающим старое имя. Согласованная защита ветки должна ссылаться на реально выполняемый результат. Pipeline, который запускается успешно, но не участвует в решении о слиянии согласно принятой политике, не выполняет эту часть задачи.

Артефакты и код выхода

Сохраняйте отчёт, нужные логи и диагностику после отказа, но не затирайте код выхода runner успешной последующей командой. Если команды объединены в shell-скрипт, явно проверьте его поведение при ошибке и публикации артефактов.

Для каждого результата должны быть commit, окружение, версия зависимостей и ссылка на запуск. Отчёты разных сборок нельзя складывать без разделения. Срок хранения выбирают так, чтобы команда успевала расследовать проблемы, не накапливая бессмысленно большие объёмы данных.

Типичные ошибки и выводы

Частые проблемы: запуск против случайного общего стенда, скрытая зависимость от локальной машины, отсутствие readiness и повтор всего pipeline до зелёного. Ещё одна ошибка — считать зелёный CI доказательством качества, не зная, какие проверки фактически выполнились.

Хорошая CI-интеграция даёт быстрый достоверный сигнал о конкретной версии продукта. Начните с малого независимого набора, проверьте его способность обнаружить специально внесённое нарушение и обеспечьте понятное расследование. После этого расширяйте покрытие и матрицу, сохраняя доверие к результату.

Что ещё почитать