はじめに
E2Eテストが壊れているのを知りながら、誰も直さない状態になったことはないだろうか。
UIのクラス名を変えたらPlaywrightのテストが軒並み失敗した。修正しようとしたら他の開発者が「後でやる」と言い、そのまま1ヶ月が経つ。CIのE2Eチェックを全員がスキップするようになっている——こういう状況はフロントエンドを含むプロジェクトでよく見かける。
原因は「テストを書く文化がない」ではなく、「セレクタが脆い」「書くコストが高い」「失敗の原因特定が難しい」という構造的な問題にある。Claude Code × Playwright はこの3つを変える。
コドモン社ではClaude Codeとスキルを組み合わせてE2Eテストを1日数十本のペースで拡充し、全体で3,000本超のテストを維持している。TestDinoの事例ではPlaywright Skillで82本のテストを1セッションで生成した。テスト開発時間を70%削減したという報告も出ている(Medium、2026年2月)。
この記事では、この結果を生む3つの設計パターン(自己修正ループ・自然言語テストランナー・ドメイン知識ファイル)を解説する。
3つのアプローチ——目的に応じて選ぶ
Claude Code × Playwright の入り口は複数あって、最初どれを選ぶかで体験がかなり変わる。
Playwright MCP——ブラウザをリアルタイム制御
Playwright MCPはClaude Codeがブラウザを直接操作するMCPサーバーだ(Microsoft公式)。
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp"]
}
}
}
~/.claude/settings.json にこれを追加すると、Claude Codeが browser_navigate(URL移動)・browser_click(クリック)・browser_fill(入力)・browser_screenshot(スクリーンショット)・browser_evaluate(JavaScript実行)を使えるようになる。
このアプローチの強みは「実際に動作確認したテスト」を生成できることだ。Claude Codeが実際にブラウザを操作しながらUIの状態を確認するため、「想像で書いたテスト」に起因する誤ったセレクタや存在しない要素のクリックが発生しにくい。
Playwright Skill——70以上のベストプラクティスを封じ込める
lackeyjb/playwright-skill はPlaywrightのベストプラクティスをClaude Code Skillとして提供するOSSだ。70以上のガイドが5つのスキルパックに整理されており、TypeScript・JavaScriptの実装例付きで提供されている。
curl -sL https://raw.githubusercontent.com/lackeyjb/playwright-skill/main/SKILL.md \
-o ~/.claude/skills/playwright/SKILL.md --create-dirs
スキルパックの内容はLocators(セレクタ戦略)、Page Objects(Page Object Modelの設計)、Assertions(正確なアサーション)、Fixtures(テストデータのセットアップ・クリーンアップ)、CI/CD(GitHub Actions・パラレル実行設定)の5つだ。
インストール後にClaude Codeへ「ショッピングカートの商品追加フローのE2Eテストを Page Object Modelパターンで書いて。data-testidセレクタを優先して使って」と指示するだけで、ベストプラクティスに準拠したテストが生成される。
自然言語テストランナー——コードを書かずにテストを定義
firstloophq/claude-code-test-runner は自然言語でE2Eテストを定義してClaude Codeが実行するテストランナーだ。
# tests/e2e/login.yaml
name: ログインフロー
steps:
- "ホームページを開く"
- "ログインボタンをクリックする"
- "メールアドレスに user@example.com を入力する"
- "パスワードに password123 を入力する"
- "ログインボタンをクリックして送信する"
- "ダッシュボードが表示されることを確認する"
- "ユーザー名が右上に表示されることを確認する"
claude-code-test-runner --test tests/e2e/login.yaml
Claude Codeが自然言語のステップを解釈し、Playwright MCP経由でブラウザを操作して各ステップを実行・検証する。Playwrightのコードを書かずにYAMLで記述するため、QAエンジニアや非エンジニアでも参加しやすい。セレクタの特定をClaude Codeが毎回文脈から判断するため、UIのクラス名が変わってもテスト定義を修正する必要がない(セルフヒーリング)。
自己修正ループ——スクリーンショットで視覚的に検証する
Anthropicの公式ベストプラクティスで推奨されているアプローチの一つに、Claude が自己検証できるようにすることがある。テスト・スクリーンショット・期待される出力をClaude Codeに渡すことで、修正サイクルが短くなる。
E2Eテストでの自己修正ループはこうなる。
Claude Codeがテストコードを書く
↓
Playwright MCPでテストを実行
↓
スクリーンショットで現在の画面状態を確認
↓
期待値とのズレを発見
↓
テストコードを修正(セレクタ・アサーション)
↓
再実行 → パス
プロンプトに「書いた後に実際にPlaywright MCPで実行して、失敗したら原因を分析して修正してから報告して。スクリーンショットを撮って画面状態を確認しながら進めて」と入れることで、このループが自動で回る。
従来のPlaywrightテストはセレクタが変わると即座に壊れる。
// 脆いセレクタ(クラス名が変わると壊れる)
await page.click('.btn-primary-submit-v2');
Claude Code + Playwright MCPによるセルフヒーリングはこうなる。
セレクタが見つからない
↓
スクリーンショットで現在のUIを確認
↓
「送信ボタン」に相当する要素を視覚的に探索
↓
aria-label・role・data-testidで再特定
↓
テストを自動修正
Playwright Skillを使っている場合は最初から data-testid や aria-label を優先して使うため、そもそもクラス名に依存した脆いセレクタが生成されない。
ドメイン知識ファイル——「想像で書く」問題を解決する
Claude CodeにURLを与えてE2Eテストを生成させると、実際のUIを見ずに「こういう画面のはず」と推測してテストを書くことがある。存在しないボタンのクリック、間違ったフォームの順番、テスト環境固有の制約の欠落——これらがE2E生成の品質を下げる。
解決策は画面ごとのドメイン知識ファイルを用意することだ。
.claude/
└── knowledge/
└── ui/
├── login/
│ ├── page.md # ページの説明・セレクタ・注意事項
│ └── screenshots/
│ ├── login-form.png
│ └── login-error.png
└── dashboard/
├── page.md
└── screenshots/
# .claude/knowledge/ui/login/page.md
ログイン画面
ユーザー認証を行うフォーム。
要素
- メールアドレス入力:
data-testid="email-input"
- パスワード入力:
data-testid="password-input"
- 送信ボタン:
data-testid="login-btn" テキストは「ログイン」
- エラーメッセージ:
data-testid="error-message" 認証失敗時のみ表示
テスト注意事項
- テスト環境ではCAPTCHAが無効化されている(本番では有効)
- アカウントロックは5回連続失敗で発動(テスト後にリセットが必要)
- SSO有効のアカウントはこのフォームではなくSSOリダイレクトになる
このファイルを作ることで、AIが実際のセレクタ・テスト環境固有の制約・エッジケースを把握した上でテストを生成する。コドモン社の事例によると、40ページ未満のアプリで1プラットフォームあたり数営業日の初期投資で構築できる。Playwright CLIで自動スクリーンショットを取得しながら作ると効率的だ。
CLAUDE.mdで「いつE2Eテストを書くか」を自動化する
実装が終わった後にE2Eテストを「書かないといけない」と思い出す——この構造を変えるには、CLAUDE.mdに生成ルールを書いておくことが有効だ。
## E2Eテスト生成ルール
自動生成トリガー
以下の実装が完了したタイミングでPlaywrightのE2Eテストを自動生成すること:
- 新しいフォームの追加
- ページ遷移の変更
- 認証フローの変更
テスト設計原則
- セレクタは
data-testid を最優先(なければ aria-label・role)
- 各テストは独立して実行できるようにする(前のテストの状態に依存しない)
- tests/e2e/ に配置し、機能ごとにディレクトリを分ける
実行確認
- テスト生成後はPlaywright MCPで実行して動作確認すること
- 失敗した場合は原因を分析して修正してから報告すること
これで「フォームを追加した」タイミングで自動的にE2Eテストの生成が促される。
Before/After
Before(手動でE2Eテストを書いている場合)
新機能の実装完了
↓
「E2Eテストも書かないと」(後回し)
↓
1週間後にようやく書き始める
↓
UIのクラス名を見ながらセレクタを手書き
↓
3週間後、UIリファクタリングでセレクタが全部変わる
↓
「直す時間がない」→ テストがスキップされ放置へ
After(Claude Code + Playwright スタック)
新機能の実装完了(CLAUDE.mdの自動生成ルールが発動)
↓
Claude Codeが実際にブラウザを操作して動作確認
→ data-testidセレクタを優先したテストコードを生成
↓
Playwright MCPで自動実行・スクリーンショット確認
→ 失敗したら自己修正してからコミット
↓
3週間後、UIリファクタリング
→ 自然言語テストランナーの「ログインボタンをクリック」は変わらない
→ Claude Codeがセレクタを再探索して自己修正(セルフヒーリング)
↓
E2Eテストが常に動く状態を維持
まとめ
E2Eテストが壊れたまま放置されているプロジェクトを何度か見てきたが、どれも同じ構造だった。セレクタが脆くて、書くコストが高くて、失敗の原因が分かりにくい。この3つが揃うと、誰も直さなくなる。
どこから始めるかで迷う場合は、この順番がやりやすいと思う。
今すぐ(5分):npx @playwright/mcp でPlaywright MCPを設定し、「現在のプロジェクトのログインフローのE2Eテストを書いて。Playwright MCPで実際に動作確認しながら生成して」と依頼する。
今日中:CLAUDE.mdに「フォーム追加・ページ遷移変更時にE2Eテストを自動生成する」ルールと「data-testidセレクタを優先する」規約を追記する。
チーム展開:lackeyjb/playwright-skill をインストールし、E2Eテストが壊れやすいページから優先的にドメイン知識ファイルを構築する。「AIが想像でテストを書く」問題が解消されると、生成されるテストの品質が一段上がる。

コメント