Автотест, который запускают руками «когда вспомнят», почти бесполезен. Ценность появляется, когда тесты сами гоняются на каждое изменение и быстро говорят «можно мержить» или «нельзя».
Где и когда запускать
| Событие | Что запускать | Цель по времени |
|---|---|---|
| Пул-реквест | линтеры, unit, смоук API и UI | до 10-15 минут |
| Мерж в основную ветку | расширенный набор, деплой на стенд | до 30 минут |
| Ночью | полный регресс, кросс-браузер | часы допустимы |
| После деплоя | смоук на окружении | минуты |
Набор на пул-реквест должен быть обязательной проверкой (required check), иначе красный статус игнорируют.
Пример на GitHub Actions
jobs:
e2e:
runs-on: ubuntu-latest
container: mcr.microsoft.com/playwright:v1.50.0-noble
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4]
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npx playwright test --shard=${{ matrix.shard }}/4
env:
BASE_URL: ${{ vars.STAGE_URL }}
TEST_PASSWORD: ${{ secrets.TEST_PASSWORD }}
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: report-${{ matrix.shard }}
path: playwright-report/
Что здесь важно: образ с уже установленными браузерами (тег образа держат в той же версии, что пакет @playwright/test), секреты из хранилища CI, отчёт выгружается даже при падении, fail-fast: false, чтобы одна упавшая часть не отменяла остальные.
Параллельность на одной машине и на многих
- Воркеры (процессы на одной машине):
workersв Playwright,pytest -n 4с pytest-xdist. Упираются в CPU и память агента. - Шардинг (несколько машин): каждая берёт свою долю. Playwright
--shard=2/4, в GitLab CIparallel: 4и переменныеCI_NODE_INDEX,CI_NODE_TOTAL. Отчёты потом объединяют: у Playwright есть blob-репортер иnpx playwright merge-reports.
Делить можно по количеству тестов или по времени. По количеству просто, но если в одной части оказались все медленные тесты, общий прогон будет ждать её. Деление по истории длительностей выравнивает время частей.
Изоляция: главное условие параллельности
Параллельные тесты не должны делить изменяемое состояние:
- каждый тест создаёт свои данные с уникальными именами;
- на воркер свой пользователь (индекс воркера:
workerIndexв Playwright,worker_idв xdist); - никаких «очистить всю базу» в начале теста;
- тесты, которым правда нужен порядок, явно помечены и выполняются последовательно.
Окружения
Тесты на общем стенде страдают от чужих деплоев и данных. Лучше поднимать окружение на прогон: services в CI или docker compose с базой и приложением, testcontainers в коде тестов. Для UI-тестов пул-реквестов популярны временные стенды на ветку.
Скорость пайплайна
- Кешировать зависимости (
actions/setup-nodeсcache, кеш pip). - Запускать только затронутое (по путям изменённых файлов, test impact analysis), полный набор ночью.
- Сначала быстрые проверки, потом медленные: нет смысла гонять E2E, если упал линтер.
- Следить за трендом времени прогона: он растёт незаметно.
Флаки в CI
Ретрай с отчётом о flaky, карантин, обязательная выгрузка трейсов и логов. Красный билд из-за флаки хуже, чем отсутствие теста: учит команду игнорировать красный.
Частые ошибки
- Секреты и пароли в репозитории.
- Артефакты выгружаются только при успехе, а нужны как раз при падении.
- Параллельность включили, а данные общие.
- Один шард идёт 25 минут, остальные по 5.
- Тесты не блокируют мерж, и красный статус никто не смотрит.
Что спросят на собесе
- Как у вас были встроены автотесты в CI, что запускается на пул-реквест, а что ночью?
- Чем воркеры отличаются от шардинга?
- Как обеспечить изоляцию данных при параллельном запуске?
- Как ускорить пайплайн, который идёт час?
- Как передаются секреты и где смотреть отчёт об упавшем тесте?