Merge Reports trên CI (Gộp kết quả khi sharding nhiều máy)
automationplaywright
Khi chia test suite thành nhiều shard chạy song song trên nhiều máy CI, mỗi shard sinh ra một report riêng không thể xem chung. Playwright giải quyết bằng blob reporter (xuất kết quả nén chứa đủ trace/screenshot) và lệnh npx playwright merge-reports để gộp tất cả thành một report thống nhất sau khi mọi shard xong.
Khái niệm & Bản chất
- Sharding = chia suite thành N phần bằng
--shard=1/4...--shard=4/4, mỗi phần chạy trên một máy/job CI riêng → rút ngắn wall-clock time của suite lớn. - Vấn đề: HTML reporter render ngay tại thời điểm chạy — 4 shard sinh 4 report độc lập, không có cách xem tổng quan cả run.
- Blob reporter xuất file
.zipvàoblob-report/chứa raw test result + TOÀN BỘ artefact (trace, screenshot, video) — đây là định dạng trung gian thiết kế riêng để merge. npx playwright merge-reportsđọc tất cả file blob trong một thư mục rồi render lại thành bất kỳ reporter nào (--reporter html,junit,json...) — một report duy nhất cho cả run.- Quy trình chuẩn: mỗi shard job upload
blob-report/làm artifact → job cuốineedstất cả shard, download về chung thư mục → merge → upload HTML report cuối.
Cách hoạt động & API chính
- Bật blob trên CI qua config
reporter: [['blob']]hoặc CLI--reporter=blob; thư mục output mặc địnhblob-report/, đổi bằng envPLAYWRIGHT_BLOB_OUTPUT_DIRhoặc optionoutputDir. - Cú pháp merge:
npx playwright merge-reports --reporter html ./all-blobs— tham số cuối là thư mục chứa các file.zipblob; output mặc định raplaywright-report/. --reportercủa merge-reports chấp nhận MỌI reporter — chạy lại lệnh vớijunithayjsonđể xuất thêm định dạng khác từ cùng bộ blob.--shard=i/Ndo Playwright tự chia test (theo file/case) đều nhất có thể giữa N phần; mỗi shard phải chạy CÙNG lệnh với cùng N.- Vì mỗi shard là một test run độc lập, globalSetup/teardown chạy riêng trên từng máy — cần tính đến khi thiết kế seed dữ liệu.
Ví dụ & Cú pháp thực tế
- Config reporter cho CI sharded:
``
ts // playwright.config.ts export default defineConfig({ // trên CI: blob để merge + github annotate PR; local: html như thường reporter: process.env.CI ? [['blob'], ['github']] : [['html', { open: 'never' }], ['list']], });`` - Workflow GitHub Actions hoàn chỉnh — 4 shard + job merge:
``
yaml # .github/workflows/playwright.yml jobs: test: runs-on: ubuntu-latest strategy: fail-fast: false # một shard fail không huỷ shard khác matrix: shardIndex: [1, 2, 3, 4] shardTotal: [4] steps: - uses: actions/checkout@v4 - run: npm ci - run: npx playwright install --with-deps - run: npx playwright test --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} - uses: actions/upload-artifact@v4 if: always() # fail cũng phải upload blob with: name: blob-report-${{ matrix.shardIndex }} path: blob-report retention-days: 1 merge-report: if: always() # chạy kể cả khi có test fail needs: [test] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci # cần playwright CLI cùng version để merge - uses: actions/download-artifact@v4 with: path: all-blobs pattern: blob-report-* merge-multiple: true # xả nén mọi blob về chung 1 thư mục - run: npx playwright merge-reports --reporter html ./all-blobs - uses: actions/upload-artifact@v4 with: name: html-report path: playwright-report`` - Merge tay trên máy local để kiểm tra:
``
bash # giả sử đã tải blob của các shard về ./all-blobs npx playwright merge-reports --reporter html ./all-blobs npx playwright show-report # xem report đã gộp # xuất thêm junit từ cùng bộ blob cho hệ thống khác npx playwright merge-reports --reporter junit ./all-blobs``
Best practices & Khi nào dùng
- Trên CI có sharding thì bắt buộc dùng
blobcho bước chạy test —htmlchỉ render ở bước merge; đừng cấu hình html ở shard job. if: always()cho cả upload artifact lẫn job merge — quan trọng nhất lúc test FAIL mới là lúc cần report; shard fail mà không upload blob thì report thiếu một góc.fail-fast: falsetrong matrix strategy — để một shard đỏ không giết luôn các shard còn lại, vẫn có đủ kết quả để merge.merge-multiple: truecủaactions/download-artifact@v4xả nén tất cả artifact khớppatternvào một thư mục — đúng format merge-reports cần.- Từ cùng bộ blob có thể xuất nhiều định dạng: chạy
merge-reportsnhiều lần với--reporter html,--reporter junit... cho từng consumer.
Gotchas, So sánh & Lưu ý
- Blob phải được tạo bởi cùng phiên bản Playwright — job merge phải
npm ciđúng lockfile; lệch version có thể lỗi khi đọc file zip. - Merge chỉ gộp KẾT QUẢ — nó không chạy lại test nào; retry/flaky vẫn hiển thị đúng từng attempt như trên từng shard.
- Sharding không có cơ chế điều phối dữ liệu — test ở các shard chạy đồng thời trên các máy khác nhau, nếu cùng ghi một DB/staging thì vẫn đạp nhau như thường.
--shardchia theo số lượng test ước lượng, không cân bằng thời lượng — một shard toàn test nặng sẽ chạy lâu hơn; có thể kết hợp tag hoặc tách project để cân.- Quên
retention-dayscho blob artifact thì tốn quota storage CI vô ích — blob chỉ cần sống đến lúc merge xong. - Với runner khác (GitLab, Jenkins): nguyên tắc giống hệt — stage test parallel lưu
blob-report/vào artifacts, stage cuối download hết về một folder rồi chạymerge-reportstrong image có cùng version Playwright.
