🎭

【Playwright】GitHub Actionsでブラウザごとのテストを並列実行する方法

2023/06/26に公開

はじめに

Playwright を使うと任意のブラウザで E2E テストを実行できます。テストするブラウザの種類が増えれば、それだけテストにかかる時間も増えていきます。本記事では、ブラウザごとのテストを並列で実行し、実行時間を短くする方法を紹介します。

ブラウザごとのテストを並列で実行した結果

まず初めに、初期設定(直列)で実行した場合とブラウザごとのテストを並列で実行した場合の実行時間を見ていきます。

Before

直列でテストを実行した場合は5分ほどかかっています。

初期設定のまま

After

並列化した結果、2分ほど短くなっていることが分かります。

ブラウザごとにジョブを分けて並列実行

ブラウザごとに並列実行するワークフロー

最終的には下記のようなワークフローになりました。
重要な部分にコメントを入れているので、順に説明していきます。

.github/workflows/playwright.yml
name: Playwright Tests
on:
  push:
    branches: [ main, master ]
  pull_request:
    branches: [ main, master ]
jobs:
  test:
    timeout-minutes: 60
    runs-on: ubuntu-latest
    # 1. テストしたいブラウザを列挙する
    strategy:
      matrix:
        browser: [chromium, firefox, webkit]
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-node@v3
      with:
        node-version: 16
    - name: Install dependencies
      run: yarn install
    - name: Install Playwright Browsers
      # 2. 対象のブラウザのみをインストールする
      run: npx playwright install --with-deps ${{ matrix.browser }}
    - name: Run Playwright tests
      # 3. 対象のブラウザでテストする
      run: npx playwright test --project=${{ matrix.browser }}
    - uses: actions/upload-artifact@v3
      if: always()
      with:
        name: playwright-report
        path: playwright-report/
        retention-days: 30

解説

1. テストしたいブラウザを列挙する

GitHub Actions の matrix という機能を使うことで、異なるパラメータでの並列実行が簡単に設定できます。
https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs

今回は対象のブラウザをパラメータとして列挙しています。基本的には Playwright の設定ファイルで projects として定義しているものを指定するのが良いと思います。

下記は Playwright をセットアップした時に自動で定義されている projects ですが、この場合は chromium、firefox、webkit の3つになります。

playwright.config.ts
export default defineConfig({
  ...

  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },

    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },

    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },
  ],
});

2. 対象のブラウザのみをインストールする

npx playwright install --with-deps <ブラウザ名> のように指定することで、対象のブラウザのみをインストールできます。ブラウザ名には matrix のパラメータとして列挙したブラウザ名が入ってきます。
https://playwright.dev/docs/browsers#install-system-dependencies

3. 対象のブラウザでテストする

npx playwright test --project=<ブラウザ名> のように指定することで、対象のブラウザでのみテストを実行できます。2. と同様で、ブラウザ名には matrix のパラメータとして列挙したブラウザ名が入ってきます。
https://playwright.dev/docs/test-projects#run-projects

おわりに

簡単にではありますが、ブラウザごとにテストを並列化して実行時間を短くする方法を説明していきました。もっと良い方法などあればコメントで教えていただけると嬉しいです🙏

おまけ:matrixのパラメータにshardを追加する

コストよりもワークフローの実行時間の短縮を優先したい場合は shard を指定することで更に実行時間を短くできます。
https://playwright.dev/docs/test-parallel#shard-tests-between-multiple-machines

.github/workflows/playwright.yml
name: Playwright Tests
on:
  push:
    branches: [ main, master ]
  pull_request:
    branches: [ main, master ]
jobs:
  test:
    timeout-minutes: 60
    runs-on: ubuntu-latest
    strategy:
      matrix:
        browser: [chromium, firefox, webkit]
+       shard: [1/3, 2/3, 3/3]
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-node@v3
      with:
        node-version: 16
    - name: Install dependencies
      run: yarn install
    - name: Install Playwright Browsers
      run: npx playwright install --with-deps ${{ matrix.browser }}
    - name: Run Playwright tests
+     run: npx playwright test --project=${{ matrix.browser }} --shard=${{ matrix.shard }}
    - uses: actions/upload-artifact@v3
      if: always()
      with:
        name: playwright-report
        path: playwright-report/
        retention-days: 30

実行結果

参考

Discussion