Wiki

← Tất cả bài wiki

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 .zip vào blob-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ối needs tấ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 định blob-report/, đổi bằng env PLAYWRIGHT_BLOB_OUTPUT_DIR hoặc option outputDir.
  • 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 .zip blob; output mặc định ra playwright-report/.
  • --reporter của merge-reports chấp nhận MỌI reporter — chạy lại lệnh với junit hay json để xuất thêm định dạng khác từ cùng bộ blob.
  • --shard=i/N do 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 blob cho bước chạy test — html chỉ 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: false trong 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: true của actions/download-artifact@v4 xả nén tất cả artifact khớp pattern và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-reports nhiề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.
  • --shard chia 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-days cho 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ạy merge-reports trong image có cùng version Playwright.