core code helper

Автотести в CI: шардинг, ретраї та звіти, які читають

Як запускати набір автотестів у пайплайні так, щоб він був швидким, давав зрозумілий результат і не перетворювався на «червоний за замовчуванням».

0 імпортували Імпортувати собі

Автотести, які запускаються вручну раз на тиждень, мало чого варті. Їхня сила — у швидкому зворотному зв'язку на кожну зміну. Але щойно тести потрапляють у CI, з'являються нові питання: як не чекати годину, що робити з нестабільними тестами і як показати результат так, щоб його читали.

Що і коли запускати

Подія Що запускаємо Ліміт часу
Кожен push у пул-реквест Лінтер, юніт, API-тести, smoke E2E до 10 хв
Мердж у main Повний E2E на staging до 30 хв
Щоночі Повна регресія, кросбраузерні тести, навантажувальний smoke без жорсткого ліміту
Перед релізом Регресія + ручне дослідницьке тестування —
Порада

Позначайте тести тегами (@smoke, @regression, @slow) і запускайте різні набори на різних етапах: npx playwright test --grep @smoke.

Шардинг: ділимо набір між машинами

# .github/workflows/e2e.yml
name: e2e
on: [pull_request]

jobs:
  e2e:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        shard: [1, 2, 3, 4]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm
      - run: npm ci
      - run: npx playwright install --with-deps chromium
      - run: npx playwright test --shard=${{ matrix.shard }}/4 --reporter=blob
        env:
          BASE_URL: ${{ vars.STAGING_URL }}
      - uses: actions/upload-artifact@v4
        if: ${{ !cancelled() }}
        with:
          name: blob-report-${{ matrix.shard }}
          path: blob-report
          retention-days: 7

  report:
    needs: e2e
    if: ${{ !cancelled() }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci
      - uses: actions/download-artifact@v4
        with:
          path: all-blob-reports
          pattern: blob-report-*
          merge-multiple: true
      - run: npx playwright merge-reports --reporter html ./all-blob-reports
      - uses: actions/upload-artifact@v4
        with:
          name: html-report
          path: playwright-report

Чотири шарди — набір на 20 хвилин проходить приблизно за 5–6. fail-fast: false важливий: падіння одного шарду не повинне зупиняти інші, інакше ви не побачите повної картини.

Ретраї: інструмент діагностики

Один ретрай у CI допомагає відрізнити нестабільний тест від зламаного:

  • впав і пройшов з другої спроби → flaky, пайплайн зелений, але тест іде в список на виправлення;
  • впав обидва рази → реальна проблема, пайплайн червоний.
Увага

Три-п'ять ретраїв «щоб точно пройшло» ховають реальні баги: race condition у продукті теж виглядає як flaky-тест. Більше одного ретраю — тривожний сигнал.

Карантин для нестабільних тестів

test('експорт звіту в PDF', {
  tag: '@quarantine',
  annotation: { type: 'issue', description: 'QA-1287: падає через таймаут генерації' },
}, async ({ page }) => {
  // ...
});

Тести з @quarantine запускаються окремим нічним джобом і не блокують пул-реквести. У кожного є тікет і власник; якщо тест у карантині довше двох тижнів — його або виправляють, або видаляють.

Звіт, який читають

Розробник має за 30 секунд зрозуміти, що зламалось. Для цього:

  • коментар у пул-реквесті з підсумком: скільки пройшло, впало, flaky, і посилання на HTML-звіт;
  • у звіті для кожного падіння — скріншот, відео і трасування;
  • назви тестів як вимоги: «користувач не може оформити замовлення з порожнім кошиком» замість test_cart_17.

Тестові дані та середовище

Більшість «нестабільних» тестів насправді страждають від середовища:

  • спільний staging, куди паралельно деплоять інші команди;
  • тестові дані, які змінив хтось інший;
  • сторонні сервіси з лімітами запитів.

Що допомагає: ефемерні середовища на пул-реквест (preview environments), створення даних через API в кожному тесті, моки для сторонніх сервісів і окремий тестовий акаунт для кожного шарду.

Чому для матриці шардів варто вимкнути fail-fast?

З fail-fast: true падіння першого шарду скасовує решту, і ви бачите лише частину проблем. Наступний прогін може впасти на іншому шарді — і так по колу. Повна картина за один прогін економить час.

Збережіть статтю собі

Увійдіть, щоб імпортувати її у власні нотатки, відмічати вивчене, ставити лайки й питати спільноту. Реєстрація безкоштовна: вхід через Google займає кілька секунд.

Увійти через Google Інші способи входу