Day 1: Playwrightの世界へようこそ
今日学ぶこと
- E2Eテストとは何か、なぜ必要なのか
- テストピラミッドの概念(Unit, Integration, E2E)
- Playwrightとは何か、その特徴と利点
- Playwright vs 他のツール(Cypress, Selenium)の比較
- Playwrightのアーキテクチャ(ブラウザプロトコルによる自動操作)
- インストールと初期セットアップ
- 最初のテストを書いて実行する
- テスト結果の見方
E2Eテストとは何か
Webアプリケーションを開発していると、「ログインフォームに入力して送信したら正しくログインできるか」「商品をカートに追加してチェックアウトまで完了できるか」といった、ユーザーの一連の操作が正しく動くかを確認する必要があります。
これを毎回手動で確認するのは、時間がかかるだけでなく、確認漏れも発生しやすくなります。
E2E(End-to-End)テストとは、実際のユーザーがブラウザでアプリケーションを操作するのと同じ流れを、プログラムで自動化して検証するテスト手法です。
flowchart LR
subgraph Manual["手動テスト"]
M1["ブラウザを開く"]
M2["フォームに入力"]
M3["ボタンをクリック"]
M4["結果を目視確認"]
end
subgraph E2E["E2Eテスト(自動)"]
E1["page.goto()"]
E2["page.fill()"]
E3["page.click()"]
E4["expect()で自動検証"]
end
M1 --> M2 --> M3 --> M4
E1 --> E2 --> E3 --> E4
style Manual fill:#f59e0b,color:#fff
style E2E fill:#22c55e,color:#fff
なぜE2Eテストが必要なのか
| 課題 | E2Eテストによる解決 |
|---|---|
| 手動テストは時間がかかる | 自動で数分〜数十分で完了 |
| 人間はミスをする | 毎回同じ手順を正確に実行 |
| リグレッション(退行)の検出が困難 | コード変更のたびに全体を自動チェック |
| 複数ブラウザでの確認が大変 | Chromium, Firefox, WebKitで自動実行 |
| CI/CDパイプラインでの品質担保 | デプロイ前に自動で品質を検証 |
テストピラミッド
ソフトウェアテストには、範囲と目的の異なる複数の種類があります。これを体系的に表現したのがテストピラミッドです。
flowchart TB
subgraph Pyramid["テストピラミッド"]
E2E["E2Eテスト\n(少数・高コスト・高信頼)"]
INT["インテグレーションテスト\n(中程度)"]
UNIT["ユニットテスト\n(多数・低コスト・高速)"]
end
E2E --> INT --> UNIT
style E2E fill:#ef4444,color:#fff
style INT fill:#f59e0b,color:#fff
style UNIT fill:#22c55e,color:#fff
| テストの種類 | 対象 | 速度 | コスト | 例 |
|---|---|---|---|---|
| ユニットテスト | 関数・コンポーネント単体 | 速い | 低い | 入力バリデーション関数のテスト |
| インテグレーションテスト | 複数コンポーネントの連携 | 中程度 | 中程度 | APIとデータベースの連携テスト |
| E2Eテスト | アプリケーション全体 | 遅い | 高い | ユーザー登録からログインまでの一連のフロー |
E2Eテストはピラミッドの頂点に位置し、数は少なくても、ユーザーにとって最も重要なシナリオをカバーします。Playwrightは、このE2Eテストを効率的に作成・実行するためのツールです。
Playwrightとは何か
Playwrightは、Microsoftが開発したオープンソースのE2Eテスト・ブラウザ自動化フレームワークです。2020年にリリースされて以降、急速に普及し、現在ではE2Eテストツールの主流の一つとなっています。
Playwrightの主な特徴
flowchart TB
subgraph Features["Playwrightの特徴"]
A["マルチブラウザ対応\nChromium / Firefox / WebKit"]
B["自動待機\nAuto-waiting"]
C["テスト分離\nBrowser Context"]
D["並列実行\nParallel Execution"]
E["強力なデバッグツール\nTrace Viewer / Inspector"]
F["多言語サポート\nTS / JS / Python / Java / C#"]
end
style Features fill:#3b82f6,color:#fff
style A fill:#8b5cf6,color:#fff
style B fill:#8b5cf6,color:#fff
style C fill:#8b5cf6,color:#fff
style D fill:#8b5cf6,color:#fff
style E fill:#8b5cf6,color:#fff
style F fill:#8b5cf6,color:#fff
- マルチブラウザ対応: Chromium(Chrome, Edge)、Firefox、WebKit(Safari)の3つのブラウザエンジンをサポート
- 自動待機(Auto-waiting): 要素がクリック可能になるまで自動的に待機。明示的なwaitやsleepが不要
- テスト分離: 各テストが独立したBrowser Contextで実行されるため、テスト間の干渉がない
- 並列実行: テストをワーカープロセスで並列に実行し、テスト時間を大幅に短縮
- 強力なデバッグツール: Trace Viewer、UI Mode、Playwright Inspectorなど
- 多言語対応: TypeScript/JavaScript、Python、Java、C# をサポート
Playwright vs 他のツール
Selenium / Cypress / Playwright の比較
| 項目 | Selenium | Cypress | Playwright |
|---|---|---|---|
| 開発元 | ThoughtWorks(2004年〜) | Cypress.io(2017年〜) | Microsoft(2020年〜) |
| 対応ブラウザ | 全主要ブラウザ | Chromium, Firefox, WebKit | Chromium, Firefox, WebKit |
| 言語 | Java, Python, C#, JS等 | JavaScript/TypeScript | JS/TS, Python, Java, C# |
| アーキテクチャ | WebDriver経由 | ブラウザ内実行 | CDPやブラウザプロトコル経由 |
| 自動待機 | なし(手動で実装) | あり | あり(より高精度) |
| 並列実行 | 外部ツール必要 | 制限あり | 標準で対応 |
| 複数タブ/ウィンドウ | 可能 | 不可 | 可能 |
| iframe操作 | 可能(やや煩雑) | 可能(制限あり) | 容易 |
| ネットワーク制御 | 制限あり | 強力 | 強力 |
| 実行速度 | 遅い | 速い | 非常に速い |
| 学習コスト | 中程度 | 低い | 低い |
Playwrightを選ぶ理由
- Seleniumより: 自動待機があり、セットアップが簡単で、実行速度が速い
- Cypressより: 複数タブ・iframe操作が可能で、マルチブラウザ対応が充実し、並列実行が標準
Playwrightのアーキテクチャ
Playwrightがどのようにブラウザを操作しているか、内部的な仕組みを理解しておきましょう。
flowchart LR
subgraph TestProcess["テストプロセス"]
T["テストコード\n(TypeScript)"]
PW["Playwright\nライブラリ"]
end
subgraph BrowserProcess["ブラウザプロセス"]
B["ブラウザエンジン\n(Chromium/Firefox/WebKit)"]
P["ページ"]
end
T --> PW
PW -->|"CDP / ブラウザプロトコル"| B
B --> P
style TestProcess fill:#3b82f6,color:#fff
style BrowserProcess fill:#8b5cf6,color:#fff
通信プロトコル
Playwrightは各ブラウザエンジン固有のプロトコルを使ってブラウザと通信します。
| ブラウザ | プロトコル | 説明 |
|---|---|---|
| Chromium | Chrome DevTools Protocol (CDP) | Chrome DevToolsと同じプロトコル |
| Firefox | Playwrightプロトコル(独自パッチ) | Firefox向けに最適化されたプロトコル |
| WebKit | Playwrightプロトコル(独自パッチ) | WebKit向けに最適化されたプロトコル |
ブラウザ内で実行されるCypressとの違い
Cypressはテストコードがブラウザ内のiframeで直接実行されます。一方、Playwrightはテストプロセスとブラウザプロセスが分離しています。この設計により、以下が可能になります。
- 複数ブラウザの同時制御: 別プロセスとして起動するため、複数ブラウザを同時に操作可能
- 複数タブ・ウィンドウの操作: ブラウザの外からコントロールするため制約がない
- ネットワークレベルの制御: ブラウザの外側からHTTPリクエスト/レスポンスをインターセプト
インストールと初期セットアップ
前提条件
- Node.js: バージョン18以上
- npm: Node.jsに同梱
- OS: Windows, macOS, Linux
プロジェクトの作成
新しいプロジェクトを作成してPlaywrightをセットアップしましょう。
# 新しいディレクトリを作成
mkdir my-playwright-project
cd my-playwright-project
# Playwrightプロジェクトを初期化
npm init playwright@latest
初期化ウィザードでは以下の質問が表示されます。
? Do you want to use TypeScript or JavaScript? · TypeScript
? Where to put your end-to-end tests? · tests
? Add a GitHub Actions workflow? · false
? Install Playwright browsers? · true
生成されるファイル構成
my-playwright-project/
├── tests/
│ └── example.spec.ts # サンプルテストファイル
├── tests-examples/
│ └── demo-todo-app.spec.ts # Todoアプリのデモテスト
├── playwright.config.ts # Playwright設定ファイル
├── package.json
├── package-lock.json
└── tsconfig.json
playwright.config.ts の基本設定
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
// テストファイルのディレクトリ
testDir: './tests',
// 各テストのタイムアウト(30秒)
timeout: 30000,
// テストの並列実行
fullyParallel: true,
// CI環境ではリトライを有効化
retries: process.env.CI ? 2 : 0,
// 並列ワーカー数
workers: process.env.CI ? 1 : undefined,
// テストレポーターの設定
reporter: 'html',
// 全テスト共通の設定
use: {
// ベースURL
baseURL: 'http://localhost:3000',
// 失敗時のトレースを記録
trace: 'on-first-retry',
// スクリーンショットの設定
screenshot: 'only-on-failure',
},
// テスト対象のブラウザ設定
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
});
主要な設定項目
| 設定項目 | デフォルト値 | 説明 |
|---|---|---|
testDir |
'./tests' |
テストファイルのディレクトリ |
timeout |
30000 | 各テストのタイムアウト(ms) |
fullyParallel |
true | テストの完全並列実行 |
retries |
0 | テスト失敗時のリトライ回数 |
workers |
CPUコア数の50% | 並列ワーカー数 |
reporter |
'list' |
テストレポーターの種類 |
use.baseURL |
なし | page.goto('/') のベースURL |
use.trace |
'off' |
トレース記録のタイミング |
最初のテストを書いてみよう
テストの基本構造
Playwrightのテストは、test 関数と expect アサーションで構成されます。
// tests/my-first-test.spec.ts
import { test, expect } from '@playwright/test';
test('Playwrightの公式サイトにアクセスできる', async ({ page }) => {
// 1. ページに移動
await page.goto('https://playwright.dev/');
// 2. タイトルが "Playwright" を含むことを検証
await expect(page).toHaveTitle(/Playwright/);
// 3. "Get started" リンクが表示されていることを検証
const getStarted = page.getByRole('link', { name: 'Get started' });
await expect(getStarted).toBeVisible();
});
テストの実行
# 全テストを実行
npx playwright test
# 特定のテストファイルを実行
npx playwright test tests/my-first-test.spec.ts
# 特定のブラウザで実行
npx playwright test --project=chromium
# UIモードで実行(インタラクティブ)
npx playwright test --ui
# ヘッド付きモードで実行(ブラウザが表示される)
npx playwright test --headed
複数のテストを書く
// tests/example.spec.ts
import { test, expect } from '@playwright/test';
test.describe('Playwright公式サイト', () => {
test('トップページにアクセスできる', async ({ page }) => {
await page.goto('https://playwright.dev/');
await expect(page).toHaveTitle(/Playwright/);
});
test('Get startedページに遷移できる', async ({ page }) => {
await page.goto('https://playwright.dev/');
// "Get started" リンクをクリック
await page.getByRole('link', { name: 'Get started' }).click();
// Installationの見出しが表示されることを検証
await expect(
page.getByRole('heading', { name: 'Installation' })
).toBeVisible();
});
test('検索機能が動作する', async ({ page }) => {
await page.goto('https://playwright.dev/');
// 検索ボタンをクリック
await page.getByRole('button', { name: 'Search' }).click();
// 検索ダイアログが表示されることを検証
await expect(page.getByRole('dialog')).toBeVisible();
});
});
テスト結果の見方
コマンドライン出力
テストを実行すると、以下のような出力が表示されます。
Running 3 tests using 3 workers
✓ 1 [chromium] › example.spec.ts:4:3 › Playwright公式サイト › トップページにアクセスできる (1.2s)
✓ 2 [chromium] › example.spec.ts:9:3 › Playwright公式サイト › Get startedページに遷移できる (1.8s)
✓ 3 [chromium] › example.spec.ts:20:3 › Playwright公式サイト › 検索機能が動作する (1.5s)
3 passed (4.2s)
テスト結果のステータス
| ステータス | 記号 | 意味 |
|---|---|---|
| Passed | ✓ | テスト成功 |
| Failed | ✗ | テスト失敗 |
| Skipped | - | テストがスキップされた |
| Timed out | ✗ | タイムアウトで失敗 |
| Flaky | ✓ | リトライで成功(不安定なテスト) |
HTMLレポート
テスト失敗時やレポート設定時に、HTMLレポートが生成されます。
# HTMLレポートを表示
npx playwright show-report
HTMLレポートでは以下の情報を確認できます。
- 全テストの結果一覧
- 各テストの実行時間
- 失敗したテストのエラーメッセージ
- スクリーンショット(設定時)
- トレース情報(設定時)
Trace Viewer
テストが失敗した原因を詳しく調べるには、Trace Viewerが非常に便利です。
// playwright.config.ts でトレースを有効化
use: {
trace: 'on-first-retry', // 最初のリトライ時にトレース記録
}
Trace Viewerでは以下を確認できます。
- テストの各ステップのスクリーンショット
- 各操作時のDOMスナップショット
- ネットワークリクエストの内容
- コンソールログ
# トレースファイルを開く
npx playwright show-trace trace.zip
まとめ
| 概念 | 説明 |
|---|---|
| E2Eテスト | ユーザー操作を自動化してアプリケーション全体を検証するテスト |
| テストピラミッド | Unit → Integration → E2E の3層構造。E2Eは少数で重要シナリオに集中 |
| Playwright | Microsoftが開発したマルチブラウザ対応のE2Eテストフレームワーク |
| 自動待機 | 要素がアクション可能になるまでPlaywrightが自動で待つ機能 |
| Browser Context | テストごとに独立したブラウザコンテキストで分離実行される仕組み |
| CDP | Chrome DevTools Protocol。PlaywrightがChromiumと通信する際のプロトコル |
| Trace Viewer | テスト実行の各ステップを詳細に確認できるデバッグツール |
重要ポイント
- E2Eテストは手動テストを自動化し、リグレッションを防ぐために不可欠
- Playwrightはブラウザプロセスの外側から制御するため、複数タブやiframeの操作が自由にできる
- 自動待機機能により、テストコードにsleepやwaitを明示的に書く必要がない
npm init playwright@latestで簡単にプロジェクトをセットアップできる
練習問題
問題1: 基本
テストピラミッドの3つの層をそれぞれ説明し、各層で書くべきテストの具体例を挙げてください。また、E2Eテストをピラミッドの頂点に配置する理由を述べてください。
問題2: 応用
PlaywrightとCypressのアーキテクチャの違いを図で説明し、Playwrightのアーキテクチャがもたらす利点を3つ挙げてください。特に、複数タブの操作が可能になる理由を述べてください。
チャレンジ問題
npm init playwright@latest で新しいプロジェクトをセットアップし、以下の要件を満たすテストを作成してください。
playwright.config.tsを編集して、Chromiumのみで実行されるようにする- 好きなWebサイトにアクセスするテストを書く
- ページタイトルの検証、特定の要素の表示確認を含める
npx playwright testで実行し、HTMLレポートを確認する
参考リンク
次回予告: Day 2では「テストの基本構造」について学びます。test.describe、test.beforeEach、test.afterEach などの構造化要素と、Playwrightのフィクスチャの仕組みを理解しましょう。