Answer
Parallel Test Execution in Playwright
Playwright supports parallel execution natively — no extra plugins or test runners needed.
How Playwright Parallelism Works
- ✓Each test runs in a separate worker process
- ✓Each worker gets its own browser, context, and page
- ✓Workers are isolated — no shared state between tests
- ✓By default: 1/2 of your CPU cores are used
Configuration
TypeScript
// playwright.config.ts
export default defineConfig({
// Run ALL tests in all files in parallel
fullyParallel: true,
// Number of workers
workers: 4, // Fixed number
workers: process.env.CI ? 2 : undefined, // 2 on CI, auto locally
});
Default Behavior (Without fullyParallel)
By default, Playwright runs test files in parallel but tests within one file run sequentially:
CODE
File A (worker 1): test1 → test2 → test3
File B (worker 2): testA → testB → testC
fullyParallel — Tests Within a File Also Run in Parallel
TypeScript
export default defineConfig({
fullyParallel: true, // test1, test2, test3 from same file run in parallel
});
Parallelize Within a Describe Block
TypeScript
test.describe.parallel('Product Tests', () => {
test('test product 1', async ({ page }) => { /* ... */ });
test('test product 2', async ({ page }) => { /* ... */ });
test('test product 3', async ({ page }) => { /* ... */ });
// All 3 run simultaneously
});
Sequential Tests (Disable Parallelism for a Group)
TypeScript
test.describe.serial('Checkout Flow', () => {
// These run one after another, in order
test('add item to cart', async ({ page }) => { /* ... */ });
test('proceed to checkout', async ({ page }) => { /* ... */ });
test('complete payment', async ({ page }) => { /* ... */ });
});
Sharding Across Multiple Machines (CI)
Bash
# CI Pipeline: 4 machines running simultaneously
# Machine 1 — runs 25% of tests
npx playwright test --shard=1/4
# Machine 2
npx playwright test --shard=2/4
# Machine 3
npx playwright test --shard=3/4
# Machine 4
npx playwright test --shard=4/4
Worker Configuration in CI
TypeScript
// playwright.config.ts
export default defineConfig({
workers: process.env.CI ? 4 : undefined,
retries: process.env.CI ? 2 : 0,
fullyParallel: true,
});
Avoid Shared State in Parallel Tests
TypeScript
// BAD — tests share global state
let userId: string;
test.beforeAll(() => { userId = createUser(); });
// GOOD — each test creates its own data
test('create user', async ({ page, request }) => {
const user = await request.post('/api/users', {
data: { email: `user-${Date.now()}@test.com` },
});
// Use unique user per test
});
