"30분 E2E suite 가 3 × 10분 병렬 shard 로 쪼개져. 같은 coverage, wall-clock 시간 1/3."
왜 Sharding
CI 피드백 시간은 feature. 개발자가 merge 전 초록 기다리고; 긴 CI = 느린 팀. E2E 테스트가 제품 성숙하면서 unit 테스트보다 빠르게 자라, 잘 모양 잡힌 suite 도 결국 '너무 느림' 벽 때림. Sharding 이 표준 답: 테스트 세트를 N 조각으로 쪼개고, 각 조각을 별개 CI 머신에서 병렬 돌리고, 결과 병합.
Playwright 에 sharding 내장. --shard=1/3 가 "발견된 테스트의 첫 1/3 돌려."--shard=2/3 가 두 번째. 각자 다른 shard arg 가진 CI job 셋 스폰하고, 병렬화 완료.
Blob Reporter — 누락된 조각
Sharded run 이 N 별개 리포트 생성. Blob reporter (--reporter=blob) 가 shard 당 compact 바이너리 리포트 작성. 최종 'merge' job 이 모든 blob 다운로드해서 npx playwright merge-reports 통해 하나의 HTML 리포트로 병합. 팀이 N 별개 대신 통합된 리포트 하나 봐.
이게 표준 CI 파이프라인 모양:
Test job (N 의 matrix) — 각자 npx playwright test --shard=$INDEX/$TOTAL --reporter=blob 돌리고, 자기 blob 업로드.
Merge job — 모든 test job 에 의존, 모든 blob 다운로드, npx playwright merge-reports --reporter=html ./all-blob-reports 실행.
Upload job — 병합된 HTML 리포트를 artifact 로 업로드.
GitHub Actions setup
GitHub Actions matrix 전략이 이걸 깨끗하게 만들어: matrix: { shard: [1, 2, 3] } 선언하면 병렬 job 셋 얻고, 각자 자기 shard 번호를 ${{ matrix.shard }} 로 받음. Merge job 이 모든 matrix leg 기다리려 needs: [test] 사용.
Suite 가 필요할 만큼 느려질 때까지 shard 하지 마. Blob-merge 춤이 orchestration 복잡성 추가. 10분 미만 suite 엔 sharding 이 승리 없는 오버헤드. 30분 이상 suite 엔 'CI 기다렸어' 와 'CI 도는 거 잊었어' 사이 차이.
Retry vs 재현성
CI 가 retry 가 값어치하는 곳이기도 해. (process.env.CI 통해 CI 전용) retries: 2 설정이 진짜 flake 가리지 않고 진짜 네트워크 blip 잡아 — Playwright 가 retry 된 테스트를 리포트에서 'flaky' 로 마크해서 CI 가 초록일 때도 비율 봐. Flaky 비율 기어오르면 반응할 숫자 있어.
항상 업로드할 Artifact
다른 거 뭘 업로드하든 두 가지 필수:
HTML 리포트 (shard 병합 후) — 실패 brows 용.
Trace .zip 파일 (test-results/ 에서) — 특정 실패 time-travel 용.
Retention 을 ~30일로 설정해서 flake 재출현 시 run 사이 비교 가능.
로컬 vs CI 설정
가장 깔끔한 CI config 는 process.env.CI 기반으로 knob 전환:
Worker: CI 에 1 (경쟁 적음), 로컬에 '50%' (머신 사용).
Retry: CI 에 2 (네트워크 jitter 잡음), 로컬에 0 (flake 즉시 봄).
Reporter: CI 에 'blob' (sharding 용), 로컬에 'html' (brows 용).
# Local — single process, watchable
npx playwright test
# Local — simulate sharding for debugging
npx playwright test --shard=1/3 # run only the first shard locally
npx playwright test --shard=2/3
npx playwright test --shard=3/3
# Local — merge the blobs you produced into one HTML report
npx playwright merge-reports --reporter=html ./blob-report-1 ./blob-report-2 ./blob-report-3
# CI — uses the shard arg from the matrix
npx playwright test --shard=${SHARD}/${TOTAL_SHARDS} --reporter=blob
Sharded + merged run 의 모양·text
# Workflow result you should see in the GitHub Actions UI
┌──────────────┐
│ test (1/3) │ Running shard 1 of 3 ............ 9m 42s ✅
├──────────────┤
│ test (2/3) │ Running shard 2 of 3 ............ 9m 18s ✅
├──────────────┤
│ test (3/3) │ Running shard 3 of 3 ............10m 04s ✅
└──────────────┘
│
▼
┌──────────────┐
│ merge │ Downloading 3 blobs, merging .... 0m 47s ✅
└──────────────┘
Total wall time: ~11 minutes (vs ~30 minutes serial)
Artifacts: playwright-report (browseable HTML), blob-report-{1,2,3}
Click the failing test in the merged report → click 'Trace' → time-travel through the failure.
프로젝트의 CI 가 오늘 Playwright 테스트 돌리면 총 wall 시간 봐. 5분 미만이면 sharding 이 오버헤드 — 이 연습 skip. 10분 넘으면 3-shard 패턴 setup: CI 를 matrix 전략 쓰도록 업데이트, CI 에서 blob reporter 로 전환, merge job 추가. 새 wall 시간 측정 — 옛 시간의 ~1/3 봐야. 병합된 HTML 리포트가 end-to-end 작동하는지 확인 (실패에 클릭, 그것의 trace 봄).
Hint
Merge job 이 'no blob reports found' 로 실패하면 다운로드 패턴이 매칭 안 하는 거. Artifact 이름이 shard 당 unique 해야 함 (blob-report-${{ matrix.shard }}), 다운로드 패턴이 한 폴더로 통합하려 merge-multiple: true 필요.
Progress
Progress is local-only — sign in to sync across devices.