はじめに

手動のE2Eテストは、いつも「時間はかかるが省略もできない」作業です。画面を1つずつ開いて、期待通りの表示になっているか確認し、フォームを送信して結果を見る——地味ですが、ここをサボると本番でしか気づけない不具合を見逃します。

そこで「この作業、Playwright MCPを使ってコーディングエージェント(Claude Code)にどこまで任せられるのか」を、実際のアプリ(以下「テストアプリ」)で試しました。単なる感想で終わらせず、他のシステムにもそのまま応用できる構築手順と、AIにほぼ任せられる構成にするための設計のポイントを中心にまとめます。

全体の構築手順

まず、登場するものの関係を整理します。「人間」「Claude Code(AIエージェント)」「Playwright MCP」「テストコード」「対象アプリ」の5者がどう繋がっているかが分かると、以降の手順が頭に入りやすくなります。

人間
① 対象機能・テスト仕様書(or 設計書)・環境URL・ログイン情報を渡す
Claude Code
(AIエージェント)
② 仕様書を分類し、実画面をread-onlyで確認しながらテストコードを作る(この間、対象アプリへの書き込みは一切無い)
②の中でClaude Codeが同時に扱う3つの要素
テスト仕様書
(md/設計書)
読み込み・修正・書き戻し
Playwright MCP
踏査フェーズ = read-only
playwright/
テストコードを生成
③ 自動化対象/書込み系ケース/仕様書の修正箇所をまとめて提示
【人間の確認ゲート】この内容で進めてよいか?
Go
→ ④実行へ進む
修正を依頼
→ ②へ戻ってやり直す
中止
→ 何も実行せず終了
④ Goが出た後だけブラウザを操作する(ここから先で初めて書き込みが起こりうる)
ブラウザ
⑤ 画面操作・確認・(対象ケースのみ)データ送信
対象アプリ
(画面・API・DB)
⑥ 結果を「テストのミス/一時的要因/本物の不具合」に切り分け、仕様書に反映
人間へレポートを提出

青い矢印=AIが自律的に進める区間、赤い矢印=人がGoを出した後にだけ通る区間、黄色い箱=人が判断するポイント、です。

図の番号は、下の手順の番号とだいたい対応しています。ポイントは、対象アプリに実際に書き込みが起こるのは「③の確認ゲートでGoが出た後」だけという点です。それより前(①②)は、対象アプリを見に行くことはあっても、書き込みは一切発生しません。

以下の6ステップは、対象がどんなWebアプリでも基本的に同じ形で応用できます。

1
Playwright MCPをエージェントに接続する

Claude CodeにPlaywright MCPサーバーを追加します。一度接続すれば、そのマシン上のどのプロジェクトからでも呼び出せます。

claude mcp add -s user playwright -- npx -y @playwright/mcp@latest

接続直後は今動いているセッションにツールが反映されないことがあるため、セッションを開き直してmcp__playwright__*系のツールが使えるか確認します。

2
テスト仕様書を用意する(無ければAIに作らせる)

「手順」「期待結果」が書かれたテスト仕様書があれば、それをそのまま入力にします。無い場合は、設計書と実際の実装差分(diff/PR)をAIに読ませて、たたき台を作らせることもできます。ただしこの生成された仕様書は、人がレビューした仕様書と同じ信頼度では扱えません。次のステップで実画面と突き合わせて検証する前提で進めます。

3
実画面をAIに踏査させる(ここは必ず読み取り専用にする)

AIにログインさせ、対象画面を1つずつ開かせて、実際のDOM構造(要素のid・role・振る舞い)を確認させます。ここが今回の構築手順の中でも最重要ポイントです。仕様書の文章だけを読んでテストコードを書かせると、高確率で外れます。逆に、この踏査の段階でうっかりフォームを送信してしまうと、対象環境に意図しないデータを作ってしまいます。このステップは「見るだけ」に限定するルールを最初から明文化しておくべきです。

4
テストコードを生成させる

ステップ3で確認した実際のセレクタをもとに、@playwright/test形式のテストコードを生成させます。ログイン処理は役割ごとにfixtureとして共通化し、1テストケース=1シナリオIDで対応させておくと、後で失敗した時にどの仕様書の項目が壊れたのか一発で分かります。

5
実行する前に、必ず人が確認するゲートを挟む

「どのケースを自動化対象にしたか」「そのうちどれが実際にデータを書き込むか」「対象外にしたケースとその理由」をAIにまとめさせ、人がGoサインを出すまでは何も実行させません。ここを飛ばすと、AIが自分で立てた計画をAI自身がチェックすることになり、抜け漏れに気づけません。

6
実行し、失敗を切り分けてから仕様書とレポートに反映する

Goが出たら実行します。失敗したら「テストコード側のミスか」「一時的な環境要因か」「アプリの本物の不具合か」を必ず切り分けさせてから報告させます。ここを曖昧にすると、失敗件数だけが並ぶ役に立たないレポートになります。

実際に使ってみた感想・注意点

上記の手順で、既存のテスト仕様書(約90項目)のうち自動化しやすい部分をAIに任せてみました。正直、1回目でスムーズに通ったテストはほとんどありません。つまずいた点を挙げます。

注意点1: 仕様書の文章だけからセレクタを推測させると高確率で外れる

「ボタンは3つある」という前提で位置指定させたら、実際は特定の条件を選んだ時だけJSでボタンがDOMに追加される仕様で、初期状態では2つしか存在しませんでした。一覧画面も見出し用テーブルと本体用テーブルが別になっているなど、見た目だけでは分からない構造の癖が随所にありました。ステップ3の実画面踏査を省略しないことが結局一番の近道です。

注意点2: クリックより直接遷移のほうが安定することがある

iframe内に埋め込まれたSPA的な画面で、リンクを.click()させると稀に無関係な要素を誤クリックする現象がありました。href属性を取得してpage.goto()で直接遷移させる方式に切り替えると安定しました。クリックの再現に固執せず、同じ結果が得られる別の手段を選ばせる判断も必要です。

注意点3: confirm()ダイアログの挙動はツールによって違う

MCPでの手動確認時はダイアログが自動承認されているように見えましたが、生成した@playwright/testのテストランナーはデフォルトで未処理のダイアログを自動キャンセルします。この違いに気づかず、「登録ボタンを押しても何も起きない(がエラーも出ない)」という分かりにくい失敗に数十分溶かしました。

// これが無いと、確認ダイアログがある操作は静かに失敗する
page.once('dialog', (dialog) => dialog.accept());
await page.getByRole('button', { name: '登録' }).click();

自動化したテストのうち1件は、何度実行しても失敗していました。「タイトルだけ入力して下書き保存する」という、本来はエラーにならないはずの操作です。ここで「よくあるバリデーション漏れだろう」で終わらせず、AIにソースコード(Action → Service → DAO → SQLマッピング)とマイグレーション履歴を追わせたところ、原因は機能自体とは無関係な古いマイグレーションファイルのバージョン番号重複でした。あるバージョン番号が複数ファイルに重複して割り振られており、それ以降の変更(今回のバグ修正を含む)が一切DBに反映されていなかったのです。テストコードの外まで踏み込んで原因を追わせたからこそ辿り着けた結論でした。

この構成にすると、なぜAIにほぼ任せられるのか

一通り試してみて、つまずいた点をルール化し、フェーズを明確に区切ったところ、2回目以降はかなり安定して回るようになりました。ポイントは以下の3つです。

フェーズを明確に分けると、AIが迷わない

「仕様書の分類」「実画面の確認」「コード生成」「実行」を1つの指示にまとめず、明確なフェーズとして区切っておくと、AIが今どの段階にいるかを見失いません。特に「実画面の確認フェーズは読み取り専用」というルールを構造的に分離しておくことで、後段の「実行フェーズ」だけが対象環境に書き込みを行う、という線引きがぶれなくなります。

確認ゲートがあるから、任せても暴走しない

「実行する前に必ず人の承認を取る」を仕組みとして組み込んでおけば、AIに一連の作業を渡しても安心して見ていられます。承認の際に「書き込みが発生するケースはどれか」を必ず開示させるようにしたことで、共有の検証環境を汚すリスクも事前に把握できます。

失敗の三分類ルールがあるから、報告を信用できる

「テストコードのミス」「一時的要因」「本物の不具合」を必ず切り分けさせ、本物の不具合と判断した場合のみ原因調査までさせる、というルールを敷いておくと、AIからの報告をそのまま信用できるようになります。これが無いと、失敗件数だけが並ぶ報告になり、結局人が全部見直す羽目になります。

手順書として固定化する

上記のフェーズ構成・ルールを、Claude CodeのSkillという再利用可能な手順書としてまとめておくと、次回以降は「このテスト仕様書をPlaywrightで自動化して」と話しかけるだけで、同じ品質のフローを再現できます。ゼロから毎回やり方を説明し直す必要がなくなるのが、この構成にした一番の狙いです。

結局、どこまでがSkillの自動化範囲なのか

「AIにほぼ任せられる」と言っても無制限に任せているわけではありません。Skillとして固定化した範囲は次の通りです。

Skillが自動でやること 人が引き続きやること
テスト仕様書が無ければ、設計書+実装差分から生成 機能そのものを開発する
各テストケースを自動化可否・書込み有無で分類 確認ゲートでGo/修正依頼/中止を判断する
実画面をread-onlyで確認し、仕様書の誤りを修正しつつセレクタを収集 ログイン情報など、推測させてはいけない情報を渡す
Playwrightのテストコードを生成 ファイルの実アップロード・サイズ/形式エラーの確認
Goが出た後の実行と、失敗の三分類(テストのミス/一時的要因/本物の不具合) ドラッグ&ドロップ等の複雑なUI操作の確認
本物の不具合と判断した場合の原因調査 Excel等出力ファイルの中身検証、バッチ・cron処理の実行確認
テスト仕様書への結果反映とレポート提出 複数アカウントを跨ぐ操作、本番環境へのデプロイ確認

左側(Skillの範囲)は「ブラウザの画面状態を機械的に確認できるもの」に限定されているのがポイントです。右側(人の範囲)に挙がっているのは、いずれも「追加のデータ準備」「複数アカウントの同時操作」「実行してよいかの最終判断」のように、AIだけでは代替できない・代替すべきでない作業です。この線引きを最初にはっきりさせておくことが、「AIにほぼ任せる」を安全に成立させる前提になります。

まとめ

  • テスト仕様書の文章だけからコードを書かせるのではなく、必ず実画面を読み取り専用で確認させるフェーズを挟む
  • 実行前に「何を」「どこまで」自動化するかを人が確認できるゲートを設ける。ここを省略しない
  • 失敗は必ず「テストのミス/一時的要因/本物の不具合」に切り分けさせる。本物の不具合はテストコードの外まで調査させる価値がある
  • フェーズとルールを手順書として固定化しておくと、次からはAIにほぼ任せられる
おわりに

Playwright MCP自体はどんなアプリにも応用できる汎用的な仕組みですが、「どこまで自動判断させ、どこで必ず人を挟むか」の設計が、実用に耐えるかどうかを分けると感じました。

ここまで読んでいただき、ありがとうございます。もしこの記事の技術や考え方に少しでも興味を持っていただけたら、ネクストのエンジニアと気軽に話してみませんか。

  • 選考ではありません
  • 履歴書不要
  • 技術の話が中心
  • 所要時間30分程度
  • オンラインOK

エンジニアと話してみる

関連リンク

AI・クラウド・データ分析のご相談はネクスト株式会社までお問い合わせください。