You have 500 tests. Each takes 2 seconds. Total: ~17 minutes on a single machine. Not great when PRs are waiting for approval. Sharding splits those 500 tests across multiple machines running in parallel. 4 shards = ~4 minutes. That is the difference between "grab a chai" and "it is already done."
Playwright handles the splitting automatically. You just tell it which shard this machine is. Playwright hashes the test files and distributes them evenly. No manual splitting needed.
# Run shard 1 of 4
npx playwright test --shard=1/4
# Run shard 2 of 4
npx playwright test --shard=2/4
# Run shard 3 of 4
npx playwright test --shard=3/4
# Run shard 4 of 4
npx playwright test --shard=4/4name: Playwright Sharded Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
shard: [1/4, 2/4, 3/4, 4/4]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npx playwright install --with-deps
- name: Run tests (shard ${{ matrix.shard }})
run: npx playwright test --shard=${{ matrix.shard }}
- name: Upload shard report
uses: actions/upload-artifact@v4
if: always()
with:
name: report-shard-${{ strategy.job-index }}
path: playwright-report/
retention-days: 7Each shard produces its own report. You want one combined report. Use the blob reporter to produce mergeable output, then merge them in a separate job.
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shard: [1/4, 2/4, 3/4, 4/4]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npx playwright install --with-deps
- name: Run tests
run: npx playwright test --shard=${{ matrix.shard }}
- name: Upload blob report
uses: actions/upload-artifact@v4
if: always()
with:
name: blob-report-${{ strategy.job-index }}
path: blob-report/
retention-days: 1
merge-reports:
if: always()
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- name: Download all blob reports
uses: actions/download-artifact@v4
with:
path: all-blob-reports
pattern: blob-report-*
merge-multiple: true
- name: Merge reports
run: npx playwright merge-reports --reporter html ./all-blob-reports
- name: Upload merged HTML report
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 14Set fail-fast: false in the matrix strategy. Without this, if shard 1 fails, GitHub cancels shards 2, 3, and 4 immediately. You lose test results from those shards. You want all shards to finish so you see ALL failures, not just the first one.
To use blob reporter, update your playwright.config.ts:
export default defineConfig({
reporter: process.env.CI
? [['blob'], ['github'], ['list']]
: [['html', { open: 'on-failure' }]],
});How many shards should you use? Start with the number of browser projects. If you test Chromium, Firefox, and WebKit, use at least 3 shards. For large suites (500+ tests), use 4-8 shards. More shards = more parallel machines = higher cost. Find the sweet spot.
Q: What is test sharding in Playwright and how does it work?
A: Sharding splits the test suite across multiple CI machines. You pass --shard=1/4 to run only the first quarter of tests on that machine. Playwright hashes test files to distribute them evenly. In GitHub Actions, use a matrix strategy with shard values like [1/4, 2/4, 3/4, 4/4]. Each shard runs in parallel. Use the blob reporter and merge-reports command to combine results into a single HTML report. Always set fail-fast: false so all shards complete even if one fails.
Key Point: Sharding splits tests across machines. 4 shards = 4x faster. Use blob reporter + merge-reports to combine results into one report.
Key Point: Sharding splits your test suite across multiple CI machines. Use --shard=1/4 syntax and fail-fast: false.