Playwright × GitHub Actions 導入ガイド:キャッシュ最適化と並列戦略まで一気通貫
モダンな Web 開発において、E2E テストの自動化は品質保証に欠かせません。特に Playwright と GitHub Actions を組み合わせることで、強力なテスト環境を構築できます。
本記事では、Playwright を GitHub Actions に導入する基礎から、実行時間を大幅に短縮するキャッシュ最適化、そして複数のテストを効率的に実行する並列戦略まで、一気通貫で解説していきますね。初めての方でも実践できるよう、各ステップを丁寧に説明します。
背景
E2E テストの重要性
Web アプリケーション開発において、単体テストだけでは実際のユーザー体験を保証できません。ブラウザ上での動作確認が必要です。
そこで登場するのが E2E(End-to-End)テストでしょう。実際のブラウザを操作してユーザーの行動をシミュレートすることで、本番環境に近い状態での動作検証が可能になります。
Playwright と GitHub Actions の組み合わせ
以下の図は、Playwright と GitHub Actions を組み合わせた際の基本的なワークフローを示しています。
mermaidflowchart LR
developer["開発者"] -->|コード<br/>プッシュ| gh["GitHub<br/>リポジトリ"]
gh -->|トリガー| actions["GitHub<br/>Actions"]
actions -->|テスト<br/>実行| playwright["Playwright<br/>テスト"]
playwright -->|結果<br/>報告| actions
actions -->|通知| developer
Playwright は、Microsoft 製のブラウザ自動化ツールです。Chromium、Firefox、WebKit の 3 つのブラウザエンジンをサポートし、クロスブラウザテストが簡単に実現できます。
GitHub Actions は、GitHub が提供する CI/CD プラットフォームですね。コードがプッシュされたタイミングで自動的にテストを実行でき、開発フローに自然に組み込めます。
この 2 つを組み合わせることで、コード変更のたびに自動的に複数ブラウザでテストが実行され、品質を継続的に保てるようになります。
実運用における考慮事項
しかし、実際の運用では単に導入するだけでは不十分です。テストケースが増えるにつれて実行時間が長くなり、開発速度に影響を与えてしまいます。
そのため、以下の 3 つの観点が重要になってきます。
- 導入: Playwright と GitHub Actions の基本的なセットアップ
- キャッシュ最適化: 依存関係のインストール時間を短縮
- 並列戦略: 複数のテストを同時実行して全体の時間を削減
これらを適切に組み合わせることで、高速で信頼性の高いテスト環境が構築できるでしょう。
課題
テスト実行時間の肥大化
E2E テストをそのまま導入すると、複数の課題に直面します。最も顕著なのが実行時間の問題です。
以下の図は、テスト実行時間の内訳を示しています。
mermaidflowchart TD
start["テスト<br/>開始"] --> setup["環境<br/>セットアップ"]
setup --> deps["依存関係<br/>インストール"]
deps --> browser["ブラウザ<br/>インストール"]
browser --> test["テスト<br/>実行"]
test --> report["レポート<br/>生成"]
report --> finish["完了"]
style deps fill:#ffcccc
style browser fill:#ffcccc
style test fill:#ffffcc
特に問題となるのが、以下の 2 つの処理です。
依存関係のインストール
毎回 yarn install を実行すると、数百のパッケージをダウンロードする必要があります。プロジェクトの規模によっては、この処理だけで 3〜5 分かかることも珍しくありません。
ブラウザのインストール
Playwright は初回実行時にブラウザバイナリをダウンロードします。Chromium、Firefox、WebKit の 3 つをインストールすると、合計で数百 MB のダウンロードが発生してしまいます。
逐次実行による待ち時間
テストケースが増えると、すべてを順番に実行していては時間がかかりすぎます。
例えば、1 つのテストに 30 秒かかる場合、100 個のテストを実行すると 50 分必要です。これでは Pull Request のたびに長時間待つことになり、開発効率が著しく低下しますね。
リソースの非効率な利用
GitHub Actions には無料プランでも月 2,000 分の実行時間が提供されます。しかし、非効率な設定では、すぐに上限に達してしまうでしょう。
| # | 項目 | 最適化前 | 最適化後 | 改善率 |
|---|---|---|---|---|
| 1 | 依存関係インストール | 4 分 | 30 秒 | 87%削減 |
| 2 | ブラウザインストール | 2 分 | 10 秒 | 92%削減 |
| 3 | テスト実行(100 件) | 50 分 | 10 分 | 80%削減 |
これらの課題を解決するために、キャッシュ最適化と並列戦略が必要になります。
解決策
キャッシュ戦略による高速化
GitHub Actions のキャッシュ機能を活用することで、繰り返しダウンロードする必要がなくなります。
キャッシュすべき対象は以下の 3 つです。
Node modules のキャッシュ
node_modules ディレクトリをキャッシュすることで、yarn install の実行時間を大幅に短縮できます。キャッシュキーには package.json や yarn.lock のハッシュ値を使用し、依存関係が変更された場合のみ再インストールされるようにします。
Yarn キャッシュディレクトリ
Yarn 自体もキャッシュディレクトリを持っています。~/.yarn/cache をキャッシュすることで、パッケージのダウンロード時間をさらに短縮できるでしょう。
Playwright ブラウザバイナリ
Playwright のブラウザバイナリは ~/.cache/ms-playwright に保存されます。このディレクトリをキャッシュすることで、毎回のブラウザダウンロードを回避できます。
以下の図は、キャッシュを活用した最適化フローを示しています。
mermaidflowchart TD
start["ワークフロー<br/>開始"] --> cache_check["キャッシュ<br/>確認"]
cache_check -->|キャッシュ<br/>ヒット| restore["キャッシュ<br/>復元"]
cache_check -->|キャッシュ<br/>ミス| install["新規<br/>インストール"]
restore --> test["テスト<br/>実行"]
install --> save["キャッシュ<br/>保存"]
save --> test
test --> finish["完了"]
style restore fill:#ccffcc
style test fill:#ccffcc
並列実行による時間短縮
GitHub Actions のマトリックス戦略を使用することで、複数のジョブを並列実行できます。
シャーディング戦略
Playwright には組み込みのシャーディング機能があります。テストを複数のグループに分割し、それぞれ異なるジョブで実行することで、全体の実行時間を削減できますね。
例えば、100 個のテストを 5 つのシャードに分割すれば、理論上は実行時間を 1/5 に短縮できます。
ブラウザ別並列実行
異なるブラウザでのテストも並列実行できます。Chromium、Firefox、WebKit のテストを同時に実行することで、クロスブラウザテストの時間を大幅に短縮できるでしょう。
リトライとタイムアウト設定
E2E テストは、ネットワークの状態やタイミングによって不安定になることがあります。
適切なリトライ設定とタイムアウトを設定することで、一時的な問題による失敗を回避し、テストの信頼性を高められます。
具体例
それでは、実際のコード例を見ながら、具体的な実装方法を解説していきます。
プロジェクトの初期設定
まず、Playwright をプロジェクトに導入します。
Playwright のインストール
以下のコマンドで Playwright をインストールしましょう。
bash# Playwrightのインストール
yarn add -D @playwright/test
# ブラウザのインストール
yarn playwright install
Playwright 設定ファイルの作成
playwright.config.ts を作成し、基本的な設定を行います。
typescriptimport { defineConfig, devices } from '@playwright/test';
/**
* Playwright設定ファイル
* テストの実行設定、ブラウザ設定、リトライ設定などを定義
*/
export default defineConfig({
// テストファイルのディレクトリ
testDir: './tests',
// 並列実行の最大ワーカー数
fullyParallel: true,
この設定により、テストがローカルでも CI 環境でも一貫して実行できます。
typescript // CI環境での設定
forbidOnly: !!process.env.CI,
// リトライ回数(CI環境では2回)
retries: process.env.CI ? 2 : 0,
// 並列ワーカー数
workers: process.env.CI ? 1 : undefined,
});
プロジェクト設定(ブラウザ指定)
複数のブラウザでテストを実行する設定を追加します。
typescript // ブラウザ設定
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
typescript {
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
});
GitHub Actions ワークフローの基本構成
次に、GitHub Actions のワークフローファイルを作成します。.github/workflows/playwright.yml を作成しましょう。
ワークフローのトリガー設定
ワークフローがいつ実行されるかを定義します。
yaml# Playwrightテストワークフロー
name: Playwright Tests
# トリガー設定
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
プッシュと Pull Request 時に自動実行されるよう設定しています。
環境変数の定義
ワークフロー全体で使用する環境変数を定義します。
yaml# 環境変数
env:
NODE_VERSION: '20'
PLAYWRIGHT_VERSION: '1.40.0'
バージョンを環境変数化することで、更新が容易になりますね。
キャッシュ最適化の実装
ここからが重要なポイントです。キャッシュを活用して実行時間を短縮します。
Node modules キャッシュ
Yarn の依存関係をキャッシュする設定を追加します。
yamljobs:
test:
runs-on: ubuntu-latest
steps:
# リポジトリのチェックアウト
- name: Checkout code
uses: actions/checkout@v4
# Node.jsのセットアップ
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
yaml# Yarnキャッシュの復元
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- name: Cache yarn dependencies
uses: actions/cache@v3
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
yarn.lock のハッシュ値をキーにすることで、依存関係が変更された場合のみキャッシュが無効化されます。
Playwright ブラウザキャッシュ
Playwright のブラウザバイナリをキャッシュします。
yaml# Playwrightブラウザのキャッシュ
- name: Cache Playwright browsers
uses: actions/cache@v3
id: playwright-cache
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }}
restore-keys: |
${{ runner.os }}-playwright-
Playwright のバージョンをキーに含めることで、バージョンアップ時に適切に再ダウンロードされます。
依存関係のインストール
キャッシュを活用した依存関係のインストールを行います。
yaml# 依存関係のインストール
- name: Install dependencies
run: yarn install --frozen-lockfile
# Playwrightブラウザのインストール(キャッシュミス時のみ)
- name: Install Playwright browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: yarn playwright install --with-deps
cache-hit の結果を確認し、キャッシュがない場合のみブラウザをインストールすることで、時間を節約できますね。
並列戦略の実装
次に、テストを並列実行する設定を追加します。
マトリックス戦略によるシャーディング
以下の図は、シャーディングによる並列実行の仕組みを示しています。
mermaidflowchart TD
tests["全テスト<br/>100件"] --> shard1["Shard 1<br/>20件"]
tests --> shard2["Shard 2<br/>20件"]
tests --> shard3["Shard 3<br/>20件"]
tests --> shard4["Shard 4<br/>20件"]
tests --> shard5["Shard 5<br/>20件"]
shard1 --> worker1["Worker 1"]
shard2 --> worker2["Worker 2"]
shard3 --> worker3["Worker 3"]
shard4 --> worker4["Worker 4"]
shard5 --> worker5["Worker 5"]
worker1 --> result["テスト<br/>完了"]
worker2 --> result
worker3 --> result
worker4 --> result
worker5 --> result
実際の設定は以下のようになります。
yamljobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# 5つのシャードに分割
shard: [1, 2, 3, 4, 5]
fail-fast: false により、1 つのシャードが失敗しても他のシャードは継続実行されます。
シャード別テスト実行
各シャードでテストを実行するステップを追加します。
yamlsteps:
# (前述のキャッシュ設定などを含む)
# シャード別テスト実行
- name: Run Playwright tests
run: yarn playwright test --shard=${{ matrix.shard }}/5
--shard オプションにより、テストが自動的に分割されて実行されます。
ブラウザ別並列実行
さらに高度な並列化として、ブラウザごとにも並列実行できます。
yamljobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# シャードとブラウザの組み合わせ
shard: [1, 2, 3, 4, 5]
browser: [chromium, firefox, webkit]
yamlsteps:
# テスト実行(ブラウザとシャード指定)
- name: Run Playwright tests
run: |
yarn playwright test \
--project=${{ matrix.browser }} \
--shard=${{ matrix.shard }}/5
この設定により、5 シャード × 3 ブラウザ = 15 個のジョブが並列実行されます。
テスト結果とアーティファクトの保存
テスト実行後、結果を保存して後から確認できるようにします。
テストレポートの生成
Playwright は自動的に HTML レポートを生成できます。
yaml# テスト実行
- name: Run Playwright tests
run: yarn playwright test --shard=${{ matrix.shard }}/5
# テスト失敗時のスクリーンショット保存
- name: Upload test results
if: always()
uses: actions/upload-artifact@v3
with:
name: playwright-report-${{ matrix.shard }}
path: playwright-report/
retention-days: 30
if: always() により、テストが失敗した場合でもレポートがアップロードされます。
トレースファイルの保存
デバッグに役立つトレースファイルも保存しましょう。
yaml# トレースファイルの保存
- name: Upload trace files
if: failure()
uses: actions/upload-artifact@v3
with:
name: playwright-traces-${{ matrix.shard }}
path: test-results/
retention-days: 7
失敗時のみトレースを保存することで、ストレージを節約できますね。
完全なワークフロー例
これまでの設定を統合した完全なワークフローファイルは以下のようになります。
yamlname: Playwright Tests
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
env:
NODE_VERSION: '20'
PLAYWRIGHT_VERSION: '1.40.0'
jobs:
test:
runs-on: ubuntu-latest
yamlstrategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4, 5]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
yaml- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- name: Cache yarn dependencies
uses: actions/cache@v3
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
yaml- name: Cache Playwright browsers
uses: actions/cache@v3
id: playwright-cache
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }}
- name: Install dependencies
run: yarn install --frozen-lockfile
yaml- name: Install Playwright browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: yarn playwright install --with-deps
- name: Run Playwright tests
run: yarn playwright test --shard=${{ matrix.shard }}/5
yaml- name: Upload test results
if: always()
uses: actions/upload-artifact@v3
with:
name: playwright-report-${{ matrix.shard }}
path: playwright-report/
retention-days: 30
この設定により、高速で信頼性の高いテスト環境が実現できます。
サンプルテストの作成
最後に、実際のテストコード例を見てみましょう。
基本的なテストケース
tests/example.spec.ts を作成します。
typescriptimport { test, expect } from '@playwright/test';
/**
* ホームページのテスト
* タイトルとメインコンテンツの表示を確認
*/
test('ホームページが正しく表示される', async ({ page }) => {
// ページにアクセス
await page.goto('https://example.com');
typescript // タイトルの確認
await expect(page).toHaveTitle(/Example Domain/);
// メインコンテンツの確認
const heading = page.locator('h1');
await expect(heading).toBeVisible();
});
フォーム送信のテスト
より実践的なフォーム送信のテストです。
typescript/**
* お問い合わせフォームのテスト
* フォーム入力から送信完了までの流れを検証
*/
test('お問い合わせフォームが送信できる', async ({ page }) => {
// お問い合わせページにアクセス
await page.goto('https://example.com/contact');
// フォームに入力
await page.fill('input[name="name"]', '山田太郎');
await page.fill('input[name="email"]', 'taro@example.com');
typescript // メッセージを入力
await page.fill('textarea[name="message"]', 'お問い合わせ内容');
// 送信ボタンをクリック
await page.click('button[type="submit"]');
// 完了メッセージの確認
await expect(page.locator('.success-message')).toBeVisible();
});
これらのテストが、設定した並列戦略とキャッシュにより、高速に実行されます。
まとめ
本記事では、Playwright と GitHub Actions を組み合わせた E2E テスト環境の構築方法を、基本から最適化まで解説しました。
重要なポイントをまとめます。
キャッシュ最適化の効果
Node modules と Playwright ブラウザのキャッシュにより、セットアップ時間を大幅に短縮できます。特に、yarn.lock と Playwright バージョンをキーにしたキャッシュ戦略が効果的でしょう。
並列戦略による高速化
シャーディングとマトリックス戦略を組み合わせることで、テスト実行時間を理論上 1/5 以下に短縮できます。プロジェクトの規模に応じてシャード数を調整することが重要ですね。
実運用での注意点
リトライ設定とタイムアウト設定により、テストの信頼性を高められます。また、テスト結果とトレースファイルの保存により、問題発生時のデバッグが容易になります。
これらの設定を適切に組み合わせることで、開発速度を落とすことなく、高品質な Web アプリケーションを継続的に提供できるでしょう。
ぜひ、あなたのプロジェクトでも Playwright × GitHub Actions の導入を検討してみてください。最初は小さく始めて、徐々に最適化していくアプローチがおすすめです。
関連リンク
articlePlaywright × GitHub Actions 導入ガイド:キャッシュ最適化と並列戦略まで一気通貫
articlePlaywright と Selenium の違いを実測で検証:乗り換え判断チェックリスト付き
articlePlaywright とは?導入メリット・他ツールとの差分を要点で理解【初心者向け】
articlePlaywright × Allure レポート運用:履歴・トレンド・失敗分析を見える化する
articlePlaywright Debug モード活用:テストが落ちる原因を 5 分で特定する手順
articlePlaywright でアクセシビリティ自動検証:axe 連携と ARIA 検証の実例
articlegpt-oss 推論パラメータ早見表:temperature・top_p・repetition_penalty...その他まとめ
articleLangChain を使わない判断基準:素の API/関数呼び出しで十分なケースと見極めポイント
articleJotai エコシステム最前線:公式&コミュニティ拡張の地図と選び方
articleGPT-5 監査可能な生成系:プロンプト/ツール実行/出力のトレーサビリティ設計
articleFlutter の描画性能を検証:リスト 1 万件・画像大量・アニメ多用の実測レポート
articleJest が得意/不得意な領域を整理:単体・契約・統合・E2E の住み分け最新指針
blogiPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
blogGoogleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
blog【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
blogGoogleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
blogPixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
blogフロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
review今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
reviewついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
review愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
review週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
review新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
review科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来