Playwright Parallelization, Sharding, and Retries

This chapter introduces Playwright's parallel execution strategy, sharding, and failure retry mechanism to help you efficiently run large-scale test suites.


Parallel Execution

By default, Playwright uses multiple Worker processes to run tests in parallel, making full use of multi-core CPUs.

fullyParallel Configuration

fullyParallelControls whether tests within the same file run in parallel.

Example

// File path: playwright.config.ts
export default defineConfig({
  fullyParallel: true,  // Tests in the same file also run in parallel
});

WhenfullyParallel: falseWhen ..., tests within the same file run serially, while tests in different files run in parallel.

WhenfullyParallel: trueWhen ..., all tests run fully in parallel (including those in the same file).

Controlling the Number of Workers

Example

export default defineConfig({
  // Use 4 Workers
  workers: 4,

  // Use the default value locally, use a fixed value of 2 in CI
  workers: process.env.CI ? 2 : undefined,

  // Single-threaded mode (convenient for debugging)
  workers: 1,
});

Serial Tests

Usetest.describe.serialForces tests in the same group to run serially.

Example

// Serial execution — each test depends on the result of the previous test
test.describe.serial('User registration to login', () => {
  test('Step 1: Register', async ({ page }) => { /* ... */ });
  test('Step 2: Verify email', async ({ page }) => { /* ... */ });
  test('Step 3: Login', async ({ page }) => { /* ... */ });
});

Try to avoid using serial tests because they break test isolation.

If tests need to run in order, consider merging multiple steps into a single test.

Local Parallel Control

Throughtest.describe.configureYou can control the parallel mode of a single group.

Example

test.describe('A group of tests', () => {
  test.describe.configure({ mode: 'serial' });  // Force serial
  // test.describe.configure({ mode: 'parallel' }); // Force parallel

  test('A', async () => {});
  test('B', async () => {});
});

Sharding

Sharding distributes tests across multiple CI machines to shorten overall runtime.

Usage

# 机器 1:运行第 1/4 片
npx playwright test --shard=1/4

# 机器 2:运行第 2/4 片
npx playwright test --shard=2/4

# 机器 3:运行第 3/4 片
npx playwright test --shard=3/4

# 机器 4:运行第 4/4 片
npx playwright test --shard=4/4

Merging Shard Reports

After all machines finish running, merge the generated report files.

# 每台机器生成报告(不自动打开)
npx playwright test --shard=1/4 --reporter=blob

# 合并所有 blob 报告
npx playwright merge-reports --reporter=html ./all-blob-reports

Shard Configuration in GitHub Actions

Example

# File path: .github/workflows/playwright.yml
jobs
:
  test
:
    strategy
:
      fail-fast
: false
      matrix
:
        shardIndex
: [1, 2, 3, 4]
        shardTotal
: [4]
    steps
:
      - uses
: actions/checkout@v4
      - uses
: actions/setup-node@v4
      - run
: npm ci
      - run
: npx playwright test --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}

Retry Mechanism

Retries allow failed tests to automatically run again, mitigating occasional flaky factors.

Configuring Retries

Example

// File path: playwright.config.ts
export default defineConfig({
  // No retries locally (quick feedback), retry 2 times in CI
  retries: process.env.CI ? 2 : 0,
});

Setting Retries for a Single File or Group

Example

// Set retries for the entire group
test.describe.configure({ retries: 3 });

test.describe('Unstable feature (requires multiple retries)', () => {
  test('Test A', async ({ page }) => { /* ... */ });
  test('Test B', async ({ page }) => { /* ... */ });
});

Retry Strategies

StrategyDescription
Retries in CI environmentNo retries locally (quick feedback), retry 2-3 times in CI
Trace collectionCombined withtrace: 'on-first-retry', only record Trace on retries
Don't abuse retriesRetries cannot mask real bugs. If a test frequently fails and only passes after retries, you should fix the root cause.
Other Extensions