Skip to main content

分片

簡介

預設情況下,Playwright 會 平行 執行測試檔案,並努力實現您機器上 CPU 核心的最佳利用。為了實現更大的平行化,您可以通過同時在多台機器上執行測試來進一步擴展 Playwright 測試執行。我們稱這種操作模式為 "分片"。在 Playwright 中,分片意味著將您的測試分成稱為 "分片" 的較小部分。每個分片就像一個可以獨立執行的單獨工作。整個目的是分割您的測試以加快測試執行時間。

當你分片測試時,每個分片可以自行執行,利用可用的 CPU 核心。這有助於通過同時執行任務來加快測試過程。

在 CI pipeline 中,每個分片可以作為獨立的工作執行,利用 CI pipeline 中可用的硬體資源,如 CPU 核心,以更快地執行測試。

在多台機器之間分片測試

要分割測試套件,請將 --shard=x/y 傳遞到命令列。例如,要將套件分成四個部分,每個部分執行四分之一的測試:

npx playwright test --shard=1/4
npx playwright test --shard=2/4
npx playwright test --shard=3/4
npx playwright test --shard=4/4

現在,如果你在不同的工作上平行執行這些分片,你的測試套件完成速度會快四倍。

請注意,Playwright 只能分片可以平行執行的測試。預設情況下,這意味著 Playwright 將分片測試文件。了解更多其他選項,請參閱 平行處理

合併來自多個分片的報告

在前面的範例中,每個測試分片都有自己的測試報告。如果你想要一個顯示所有分片測試結果的合併報告,你可以將它們合併。

開始在 CI 上執行時將 blob 報告器添加到配置中:

playwright.config.ts
export default defineConfig({
testDir: './tests',
reporter: process.env.CI ? 'blob' : 'html',
});

Blob 報告包含所有已執行測試及其結果的資訊,以及所有測試附件,如追蹤和截圖差異。Blob 報告可以合併並轉換為任何其他 Playwright 報告。預設情況下,blob 報告將生成到 blob-report 目錄中。

要合併來自多個分片的報告,將 blob 報告文件放入單一目錄,例如 all-blob-reports。Blob 報告名稱包含分片編號,因此它們不會衝突。

之後,執行 npx playwright merge-reports 命令:

npx playwright merge-reports --reporter html ./all-blob-reports

這將產生一個標準的 HTML 報告到 playwright-report 目錄中。

GitHub Actions 範例

GitHub Actions 支援使用 jobs.<job_id>.strategy.matrix 選項 在多個工作之間分片測試matrix 選項將為提供的選項的每一種可能組合執行一個單獨的工作。

以下範例顯示如何配置一個作業,以平行在四台機器上執行測試,然後將報告合併成一個報告。不要忘記將 reporter: process.env.CI ? 'blob' : 'html', 添加到你的 playwright.config.ts 檔案中,如上面的範例所示。

  1. 首先,我們在作業配置中添加一個 matrix 選項,使用 shardTotal: [4] 選項來包含我們想要建立的分片總數,並使用 shardIndex: [1, 2, 3, 4] 來包含分片編號的陣列。
  2. 然後,我們使用 --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} 選項來執行我們的 Playwright 測試。這將為每個分片執行我們的測試命令。
  3. 最後,我們將 blob 報告上傳到 GitHub Actions Artifacts。這將使 blob 報告在工作流程中的其他作業可用。
.github/workflows/playwright.yml
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
playwright-tests:
timeout-minutes: 60
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
- name: Install dependencies
run: npm ci
- name: Install Playwright browsers
run: npx playwright install --with-deps

- name: Run Playwright tests
run: npx playwright test --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}

- name: Upload blob report to GitHub Actions Artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: blob-report-${{ matrix.shardIndex }}
path: blob-report
retention-days: 1
  1. 當所有分片完成後,你可以執行一個獨立的工作來合併報告並生成一個合併的 HTML report。為了確保執行順序,我們通過添加 needs: [playwright-tests] 使 merge-reports 工作 depend 於我們的分片 playwright-tests 工作。
.github/workflows/playwright.yml
jobs:
...
merge-reports:
# Merge reports after playwright-tests, even if some shards have failed
if: ${{ !cancelled() }}
needs: [playwright-tests]

runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
- name: Install dependencies
run: npm ci

- name: Download blob reports from GitHub Actions Artifacts
uses: actions/download-artifact@v4
with:
path: all-blob-reports
pattern: blob-report-*
merge-multiple: true

- name: Merge into HTML Report
run: npx playwright merge-reports --reporter html ./all-blob-reports

- name: Upload HTML report
uses: actions/upload-artifact@v4
with:
name: html-report--attempt-${{ github.run_attempt }}
path: playwright-report
retention-days: 14

您現在可以看到報告已經合併,並且在 GitHub Actions Artifacts 頁籤中提供了合併後的 HTML 報告。

Merge-reports CLI

npx playwright merge-reports path/to/blob-reports-dir 讀取來自傳遞目錄的所有 blob 報告,並將它們合併成單一報告。

當合併來自不同作業系統的報告時,你必須提供一個明確的合併配置,以消除應該使用哪個目錄作為測試根目錄的歧義。

支持的選項:

  • --reporter reporter-to-use

    產生哪種報告。可以用逗號分隔多個報告。

    範例:

    npx playwright merge-reports --reporter=html,github ./blob-reports
  • --config path/to/config/file

    指定包含輸出報告的 Playwright 設定檔。使用此選項傳遞額外的設定給輸出報告器。此設定檔可以與建立 blob 報告時使用的不同。

    範例:

    npx playwright merge-reports --config=merge.config.ts ./blob-reports
    merge.config.ts
    export default {
    testDir: 'e2e',
    reporter: [['html', { open: 'never' }]],
    };