Day 8: デバッグとトレース
今日学ぶこと
- Headlessモードとheadedモードの違い
- Playwright Inspector(--debugフラグ、page.pause())
- UIモード(--uiフラグ)
- Trace Viewerによるトレースの記録と閲覧
- スクリーンショットとビデオの記録
- コンソールログのキャプチャ
- スローモーション実行
- VS Code拡張機能によるデバッグ
- よく使うデバッグ戦略
Headlessモード vs Headedモード
Playwrightはデフォルトでheadlessモード(ブラウザ画面を表示しない)で実行されます。テストが失敗した原因を調べたいときは、headedモードに切り替えてブラウザの動きを目視確認できます。
# デフォルト(headless)
npx playwright test
# ブラウザを表示して実行(headed)
npx playwright test --headed
playwright.config.tsで常にheadedモードにすることも可能です。
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
headless: false, // 常にブラウザを表示
},
});
Tips: CI環境ではheadlessモードを使い、ローカル開発ではheadedモードを使うのが一般的です。
Playwright Inspector
Playwright Inspectorは、テストのステップを1つずつ実行しながら状態を確認できるインタラクティブなデバッグツールです。
--debugフラグ
# すべてのテストをデバッグモードで実行
npx playwright test --debug
# 特定のテストファイルをデバッグ
npx playwright test tests/login.spec.ts --debug
# 特定の行から開始
npx playwright test tests/login.spec.ts:15 --debug
--debugフラグを付けると、以下の動作になります。
- ブラウザがheadedモードで起動
- Playwright Inspectorウィンドウが開く
- テストが最初のアクションで一時停止
- 「Step Over」「Resume」ボタンでステップ実行
page.pause()
コード内の任意の場所にブレークポイントを設定できます。
import { test, expect } from '@playwright/test';
test('checkout flow', async ({ page }) => {
await page.goto('https://example.com/shop');
await page.getByRole('button', { name: 'Add to Cart' }).click();
// ここで一時停止してInspectorで状態を確認
await page.pause();
await page.getByRole('button', { name: 'Checkout' }).click();
await expect(page.getByText('Order confirmed')).toBeVisible();
});
Inspectorウィンドウでは以下の操作が可能です。
| 機能 | 説明 |
|---|---|
| Step Over | 次のアクションまで進む |
| Resume | 次のpause()またはテスト終了まで実行 |
| Record | ブラウザ操作をコードとして記録 |
| Pick Locator | 要素を選択してロケータを生成 |
UIモード
UIモードは、テストの実行・監視・デバッグを1つのインターフェースで行える統合ツールです。
npx playwright test --ui
UIモードの主な機能は以下の通りです。
- テスト一覧: すべてのテストファイルとテストケースを表示
- ウォッチモード: ファイル変更時に自動再実行
- タイムライン: テストの各ステップをタイムライン形式で表示
- DOMスナップショット: 各ステップ実行時のDOM状態を確認
- ネットワークログ: リクエスト/レスポンスの一覧
- フィルタリング: テスト名、ファイル名、ステータスでフィルタ
flowchart LR
subgraph UIMode["UI Mode"]
A["テスト一覧"]
B["タイムライン"]
C["DOMスナップショット"]
D["ネットワークログ"]
end
A --> B --> C
B --> D
style UIMode fill:#3b82f6,color:#fff
Tips: UIモードは日常的な開発で最も便利なデバッグツールです。テストの作成・修正中は常にUIモードを起動しておくことをお勧めします。
Trace Viewer
Trace Viewerは、テスト実行の完全な記録(トレース)を後から再生・分析できるツールです。CIで失敗したテストの調査に特に有効です。
トレースの記録設定
playwright.config.tsでトレースの記録タイミングを設定します。
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
// トレースの記録設定
trace: 'on-first-retry', // 推奨: リトライ時のみ記録
},
});
設定値の比較は以下の通りです。
| 設定値 | 動作 | 用途 |
|---|---|---|
'off' |
トレースを記録しない | デフォルト |
'on' |
常にトレースを記録 | デバッグ時 |
'on-first-retry' |
最初のリトライ時に記録 | CI推奨 |
'retain-on-failure' |
失敗時のみ保持 | CI推奨 |
テスト単位での設定
特定のテストだけトレースを有効にすることもできます。
test('complex checkout flow', async ({ page, context }) => {
// このテストだけトレースを記録
await context.tracing.start({ screenshots: true, snapshots: true });
await page.goto('https://example.com/checkout');
await page.getByLabel('Card Number').fill('4242424242424242');
await page.getByRole('button', { name: 'Pay' }).click();
await context.tracing.stop({ path: 'checkout-trace.zip' });
});
トレースの閲覧
記録されたトレースは2つの方法で閲覧できます。
# ローカルでTrace Viewerを起動
npx playwright show-trace test-results/trace.zip
# または、ブラウザベースのビューアを使用
# trace.playwright.dev にzipファイルをドラッグ&ドロップ
Trace Viewerで確認できる情報は以下の通りです。
- アクションログ: 実行された各アクション(click, fill, gotoなど)
- スクリーンショット: 各アクション前後のスクリーンショット
- DOMスナップショット: 各時点でのDOM構造
- ネットワーク: すべてのHTTPリクエスト/レスポンス
- コンソール: ブラウザのコンソール出力
- ソースコード: テストコードとの対応
スクリーンショットの記録
テスト失敗時のスクリーンショットは、問題の原因を素早く特定するのに役立ちます。
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
// スクリーンショットの設定
screenshot: 'only-on-failure', // 失敗時のみ
},
});
| 設定値 | 動作 |
|---|---|
'off' |
スクリーンショットを撮らない |
'on' |
毎テスト終了時に撮影 |
'only-on-failure' |
失敗時のみ撮影(推奨) |
テスト内で手動でスクリーンショットを撮ることも可能です。
test('visual check', async ({ page }) => {
await page.goto('https://example.com');
// ページ全体のスクリーンショット
await page.screenshot({ path: 'screenshots/homepage.png' });
// 特定要素のスクリーンショット
await page.getByRole('navigation').screenshot({
path: 'screenshots/navbar.png',
});
// フルページスクリーンショット(スクロール含む)
await page.screenshot({
path: 'screenshots/full-page.png',
fullPage: true,
});
});
ビデオ記録
テスト実行全体をビデオとして記録できます。
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
video: 'retain-on-failure', // 失敗時のみビデオを保持
},
});
| 設定値 | 動作 |
|---|---|
'off' |
ビデオを記録しない |
'on' |
常に記録 |
'retain-on-failure' |
失敗時のみ保持(推奨) |
'on-first-retry' |
最初のリトライ時に記録 |
ビデオのサイズを指定することも可能です。
export default defineConfig({
use: {
video: {
mode: 'retain-on-failure',
size: { width: 1280, height: 720 },
},
},
});
Tips: ビデオ記録はテスト実行速度に影響します。CI環境では
'retain-on-failure'を使い、必要な場合のみ保持するのがベストです。
コンソールログのキャプチャ
ブラウザのコンソール出力をテスト側でキャプチャして、アプリケーションのエラーやデバッグ情報を確認できます。
test('capture console logs', async ({ page }) => {
// コンソールメッセージを収集
const logs: string[] = [];
page.on('console', (msg) => {
logs.push(`[${msg.type()}] ${msg.text()}`);
});
// エラーを検出
const errors: string[] = [];
page.on('pageerror', (error) => {
errors.push(error.message);
});
await page.goto('https://example.com');
await page.getByRole('button', { name: 'Submit' }).click();
// JavaScriptエラーが発生していないことを確認
expect(errors).toHaveLength(0);
// デバッグ用にログを出力
console.log('Browser logs:', logs);
});
リクエストの失敗を監視することもできます。
test('monitor failed requests', async ({ page }) => {
const failedRequests: string[] = [];
page.on('requestfailed', (request) => {
failedRequests.push(`${request.method()} ${request.url()}`);
});
await page.goto('https://example.com');
// 失敗したリクエストがないことを確認
expect(failedRequests).toHaveLength(0);
});
スローモーション実行
テストの動きをゆっくり再生して、何が起きているかを目視で確認できます。
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
launchOptions: {
slowMo: 500, // 各アクション間に500msの遅延
},
},
});
コマンドラインから一時的にスローモーションを有効にすることもできます。
# headedモードと組み合わせると効果的
PWDEBUG=1 npx playwright test --headed
Tips:
slowMoはブラウザレベルのオプションなので、すべてのアクション(クリック、入力、ナビゲーション)に遅延が追加されます。デバッグ目的でのみ使用してください。
VS Code拡張機能によるデバッグ
Playwright Test for VS Code拡張機能を使うと、VS Code内で直接テストをデバッグできます。
セットアップ
- VS Code拡張機能「Playwright Test for VS Code」をインストール
- テストファイルを開く
- テスト名の左にある再生ボタンが表示される
デバッグ機能
flowchart TB
subgraph VSCode["VS Code Playwright Extension"]
A["ブレークポイント設定"]
B["ステップ実行"]
C["変数の確認"]
D["ブラウザ画面の表示"]
end
A --> B --> C
B --> D
style VSCode fill:#8b5cf6,color:#fff
VS Code拡張機能の主要な機能は以下の通りです。
| 機能 | 説明 |
|---|---|
| Run Test | テストを実行 |
| Debug Test | ブレークポイント付きでデバッグ実行 |
| Show Browser | テスト実行中のブラウザを表示 |
| Pick Locator | ブラウザ上で要素を選択してロケータを生成 |
| Record New | ブラウザ操作から新しいテストを生成 |
| Watch Mode | ファイル保存時に自動で再実行 |
ブレークポイントを使ったデバッグ
- テストコードの行番号の左をクリックしてブレークポイントを設定
- テスト名の横にある「Debug Test」ボタンをクリック
- ブレークポイントで実行が停止
- 変数の値を確認、ステップ実行で進行
よく使うデバッグ戦略
1. 段階的な絞り込み
テストが失敗したとき、以下の順番で原因を調査します。
flowchart TB
A["テスト失敗"] --> B["エラーメッセージを確認"]
B --> C["スクリーンショットを確認"]
C --> D["トレースを確認"]
D --> E["page.pause()で対話的にデバッグ"]
E --> F["原因特定・修正"]
style A fill:#ef4444,color:#fff
style F fill:#22c55e,color:#fff
2. テストの分離実行
問題のあるテストだけを実行して効率的にデバッグします。
# 特定のテストファイルだけ実行
npx playwright test tests/checkout.spec.ts
# テスト名でフィルタ
npx playwright test -g "should complete checkout"
# 特定のプロジェクト(ブラウザ)だけ実行
npx playwright test --project=chromium
3. CI環境でのデバッグ設定
CI環境ではインタラクティブなデバッグができないため、アーティファクトを充実させます。
import { defineConfig } from '@playwright/test';
export default defineConfig({
// リトライ設定
retries: process.env.CI ? 2 : 0,
use: {
// CI環境でのデバッグ用設定
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
});
4. よくある問題と対処法
| 問題 | 原因 | 対処法 |
|---|---|---|
| 要素が見つからない | ロケータが不正確 | Pick Locatorで再取得 |
| タイムアウト | 要素の表示が遅い | expectのタイムアウトを調整 |
| テストが不安定 | 非同期処理の競合 | waitForLoadState()を追加 |
| CI環境でのみ失敗 | 環境差異 | トレースをCIアーティファクトとして保存 |
まとめ
今日学んだデバッグとトレースの主要ポイントを振り返りましょう。
| ツール/機能 | 用途 | 起動方法 |
|---|---|---|
| Headedモード | ブラウザの動きを目視確認 | --headed |
| Playwright Inspector | ステップ実行・対話的デバッグ | --debug / page.pause() |
| UIモード | 統合デバッグ環境 | --ui |
| Trace Viewer | テスト実行の記録・再生 | trace: 'on' |
| スクリーンショット | 失敗時の画面状態を保存 | screenshot: 'only-on-failure' |
| ビデオ | テスト全体の動画記録 | video: 'retain-on-failure' |
| コンソールキャプチャ | ブラウザログの取得 | page.on('console', ...) |
| スローモーション | アクションの遅延再生 | slowMo: 500 |
| VS Code拡張 | IDE内デバッグ | 拡張機能インストール |
CI環境ではtrace: 'on-first-retry'、screenshot: 'only-on-failure'、video: 'retain-on-failure'の組み合わせが推奨設定です。ローカル開発では--uiモードを日常的に活用しましょう。
次回予告: Day 9では「並列実行とパフォーマンス」について学びます。テストの実行速度を最適化し、大規模なテストスイートを効率的に運用する方法を紹介します。