Skip to main content
QATraining
Back to curriculum
Chapter 5 of 7

Parallelisation, Sharding & CI

Run hundreds of tests in minutes. Configure workers, shards, retries, and wire Playwright into GitHub Actions with zero-effort reports and traces.

14 min guide4 reference questions folded into the guide material
Code samples in
Guided briefing

Parallelisation, Sharding & CI video demo

A practical screen-share style walkthrough for chapter 5, showing how the Playwright idea works in TypeScript and Java.

Briefing focus

Workers vs shards

This is a structured lesson briefing. Real video/audio can be added later as a media source.

Estimated time

10 min

  1. 1Workers vs shards
  2. 2GitHub Actions workflow

Transcript brief

Run hundreds of tests in minutes. Configure workers, shards, retries, and wire Playwright into GitHub Actions with zero-effort reports and traces. The video brief explains the mental model first, then demonstrates the workflow using the course code samples, and finishes with reliability checks you can apply in CI.

Key takeaways

  • Translate the concept into a maintainable Playwright test.
  • Understand the TypeScript and Java equivalents without changing the test intent.
  • Avoid the common source of flaky or slow end-to-end tests for this topic.

Workers vs shards

Worker
An OS process that runs tests in parallel within a single machine. Controlled by the workers config option.
Shard
A slice of the test suite distributed across multiple CI machines (e.g. shard 2/4). Use with --shard flag in CI.
Retries
Automatic re-run of failed tests. Use retries: 1 on CI, 0 locally to avoid hiding real flakiness.
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 1 : 0,
  workers: process.env.CI ? 4 : undefined,
  reporter: [['list'], ['html', { open: 'never' }]],
  use: {
    baseURL: process.env.BASE_URL ?? 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
  },
  projects: [
    { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
    { name: 'firefox', use: { ...devices['Desktop Firefox'] } },
    { name: 'webkit', use: { ...devices['Desktop Safari'] } },
    { name: 'Mobile Chrome', use: { ...devices['Pixel 7'] } },
  ],
});
A production-grade playwright.config with CI-aware settings.

GitHub Actions workflow

# .github/workflows/e2e.yml
name: E2E
on: [pull_request, push]
jobs:
  test:
    name: Playwright (shard ${{ matrix.shard }})
    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: 20, cache: yarn }
      - run: yarn install --frozen-lockfile
      - run: npx playwright install --with-deps chromium
      - run: npx playwright test --shard=${{ matrix.shard }}/4
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report-${{ matrix.shard }}
          path: playwright-report
          retention-days: 14
Shard a 400-test suite across 4 runners.

Real-life scenario · SaaS platform

From 40 min to 6 min with sharding

Situation. A SaaS product had 420 Playwright tests running in 40 minutes on one CI runner. Adding fullyParallel + 4 workers + 4 shards brought it to 6 minutes per full run. Flaky rate stayed at 0.8%. Cost per PR on GitHub-hosted runners: £0.04.

Lesson. Scale parallelism two dimensions at a time — workers (per machine) × shards (across machines) — for best throughput.

Beware shared state

Parallel tests that touch the same DB rows, accounts or fixtures will fight each other. Isolate test data — unique emails, per-test tenant IDs, or reset the DB between shards.