QA Interview Hub · База знань · Тести

System Design

CI/CD, паралелізація і шардинг

Тести в пайплайні: стадії і quality gates

Хороший пайплайн дає швидкий фідбек дешевими тестами і запускає дорогі тести тоді, коли це має сенс.

PR:      lint + typecheck -> unit -> API -> e2e smoke (5-10 хв)
main:    повний API + повний e2e (до 15 хв)
nightly: cross-browser, довгі сценарії, performance
release: smoke на staging -> deploy -> smoke у проді

Quality gate - правило, яке блокує merge або деплой. Приклади: усі unit і API тести зелені, e2e smoke зелений, покриття змінених файлів не впало. Важливо: gate має бути надійним. Якщо smoke flaky, команди почнуть його ігнорувати, і gate втратить сенс.

Що запускати на PR. Повний набір на кожен PR часто занадто дорогий. Варіанти:

  • Smoke-набір з тегом @smoke через --grep.
  • Тести, пов'язані зі зміненими файлами: у Playwright є --only-changed, який бере зміни відносно git-гілки. Працює для тестів, які імпортують змінені модулі, тож для зміни на бекенді він не допоможе.
  • Повторний запуск тільки впалих: --last-failed локально.

Для фінтеху до PR-набору я обов'язково включаю критичні гроші-сценарії: переказ, поповнення, відмова при недостатньому балансі. Їх ціна помилки найвища.

На співбесіді: Я будую пайплайн шарами: на PR швидкі перевірки і smoke, на main повний набір, вночі довгі і cross-browser тести, після деплою smoke у проді. Gate блокує merge тільки стабільними тестами, інакше команда перестає йому довіряти.

Воркери і шарди: як працює паралелізація

У Playwright два рівні паралелізму.

  • Workers - процеси на одній машині. Кожен воркер має свій браузер. Кількість обмежена CPU і пам'яттю машини.
  • Shards - розподіл набору тестів між кількома машинами через --shard=1/4, --shard=2/4 і так далі.
strategy:
  matrix:
    shard: [1, 2, 3, 4, 5, 6, 7, 8]
steps:
  - run: npx playwright test --shard=${{ matrix.shard }}/8
  - uses: actions/upload-artifact@v4
    with:
      name: blob-${{ matrix.shard }}
      path: blob-report

Після всіх шардів окремий job завантажує всі blob-звіти і викликає npx playwright merge-reports --reporter html ./all-blob-reports. Так ви отримуєте один HTML-звіт.

Важливі нюанси:

  • За замовчуванням Playwright паралелить файли, а тести всередині файлу йдуть послідовно. З fullyParallel: true паралеляться окремі тести, і шарди балансуються краще.
  • Якщо один файл містить 200 тестів, а інші по 5, без fullyParallel один шард буде набагато довшим.
  • Кількість воркерів на машині не повинна перевищувати ресурси. 8 браузерів на 2 vCPU дадуть таймаути і flaky.
  • Тести з mode: 'serial' не паралеляться всередині групи. Їх варто мінімізувати.

Метрика ефективності: різниця між найдовшим і середнім шардом. Якщо найдовший шард 14 хвилин, а середній 6, ви платите за простій.

На співбесіді: Я використовую два рівні: воркери на машині і шарди між машинами, з fullyParallel для рівномірного розподілу і blob-звітами, які зливаю в окремому job. Кількість воркерів підбираю під ресурси машини, бо перевантаження одразу дає flaky.

Швидкість фідбеку і вартість

Senior має говорити не тільки про швидкість, а й про гроші і про те, де справжнє вузьке місце.

Звідки береться час у пайплайні:

  • Старт runner і встановлення залежностей. Рішення: кеш node_modules, готовий Docker-образ з браузерами.
  • Підготовка даних і логін. Рішення: API замість UI, storageState.
  • Повільні тести. Рішення: знайти топ-20 найдовших і переписати або перенести на API.
  • Очікування середовища. Рішення: health-check перед стартом, а не sleep.

Коли додавати машини, а коли ні. Якщо тести впираються в спільний staging (БД, rate limit), додавання шардів не прискорить прогін, а збільшить таймаути. Спочатку треба знайти вузьке місце.

Ще одна оптимізація - fail fast. Опція maxFailures зупиняє прогін після N падінь. На PR це економить хвилини, коли зламано щось базове, наприклад логін.

Вартість. Порахуйте приблизно: 8 машин по 15 хвилин на кожен merge, 50 merge на день. Це вже помітні гроші. Тому nightly для рідкісних сценаріїв і smoke на PR - це не лінь, а економія.

На співбесіді: Перш ніж додавати машини, я шукаю вузьке місце: встановлення залежностей, логін через UI, найповільніші тести або перевантажене середовище. Паралелізм допомагає тільки тоді, коли середовище здатне витримати навантаження.