2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Playwright Test Agents の設計分析: LLM による探索的手法でテスト仕様書を逆生成するパイプライン

2
Posted at

1. 対象と目的

Playwright で提供される Test Agents(Planner / Generator / Healer)の設計を、JSTQB Foundation Level シラバスのテスト分類体系を参照枠として分析する。分析の対象は playwright が生成するエージェント定義ファイル(chatmode / agents.md)と公式ドキュメント(https://playwright.dev/docs/test-agents )である。

調査と実行検証を通じて明らかになったのは、このパイプラインが「探索的手法によるテスト仕様書の自動生成 → スクリプト化された回帰テストへの変換」という構造を持つこと、そしてその全工程が LLM へのプロンプトのみで構成されていることの2点である。Planner のプロセスは JSTQB の探索的テストの手法に該当するが、アウトプットはスクリプトテストの仕様書であり、既存のテスト分類に単純に当てはめることはできない。本稿ではこの構造を技術的に記述する。

2. Playwright Test Agents の構成

Playwright Test Agents は3つのエージェントで構成される。

エージェント 入力 出力 役割
Planner URL(seed テスト経由) Markdown テスト計画 テスト設計
Generator Markdown テスト計画 TypeScript テストコード(.spec.ts テスト実装
Healer 失敗したテスト名 修正済みテストコード テスト保守

3つは直列に使用することを想定しており、Planner が出力した Markdown を Generator が入力として受け取る。Generator の出力に問題があれば Healer が修正する。

公式ドキュメントのページ構成は Introduction / Getting Started / 各エージェントの Input・Output / Artifacts and Conventions のみで、詳細な利用手順やチュートリアルは記載されていない。実質的にはエージェント定義ファイル内のプロンプトが最も詳細な仕様書として機能している。

3. エージェントの実体

エージェント定義ファイルの構造は以下の通りである。

.chatmode.md(VS Code 版)/ .claude/agents/*.md(Claude Code 版)
├── YAML frontmatter
│   ├── description / name
│   └── tools: [使用可能なツールのリスト]
└── Markdown 本文(LLM へのシステムプロンプト)

npx playwright init-agents--loop オプションに応じて異なる形式のファイルを生成する。

オプション 生成先 ツール名形式 追加ファイル
--loop=vscode .github/chatmodes/ playwright-test/browser_click なし
--loop=claude .claude/agents/ mcp__playwright-test__browser_click .mcp.json

プロンプト本文は両環境で完全に同一である。差異はメタデータ形式(YAML キー名、ツール名の prefix、組み込みツール名)に限定される。VS Code 版では search/fileSearch だったものが Claude Code 版では Glob になるなど、プラットフォーム固有のツール名に変換されているが、LLM への行動指示は変わらない。

つまり Playwright Test Agents とは、LLM へのプロンプト + MCP ツールの組み合わせ であり、特定のプラットフォームに依存しない。GitHub Copilot は LLM を提供するプラットフォームの一つであって、エージェントそのものではない。

4. 探索的テストとしての分類

4.1 JSTQB の定義との照合

JSTQB Foundation Level シラバス 4.4 では、探索的テストを「テスト設計、テスト実行、テスト記録、学習を同時に行う」技法と定義している。

Planner の プロセス はこの定義に合致する。Planner は browser_snapshot でページのアクセシビリティツリーを取得し、browser_click 等でUIを操作しながらアプリケーションの機能を発見し、発見した機能からテストシナリオを設計し、Markdown として記録する。設計・実行・記録が同時に進行する。

しかし、Planner の アウトプット は探索的テストのそれとは異なる。探索的テストの主な成果物はセッションノートや発見したバグであるのに対し、Planner が出力するのはステップと期待結果が明記された構造化テスト仕様書である。実際に生成された specs/the-internet.md は「1. Navigate to ... / 2. Enter ... / Expected Results: ...」というスクリプトテストのフォーマットであり、Planner 自身がテスト中にバグを発見することはない。

探索的テスト(JSTQB) Planner の実態
主な成果物 セッションノート、発見したバグ 構造化されたテスト仕様書(Markdown)
テスト中にバグを発見するか する(主目的) しない(計画を作るだけ)
出力の形式 非定型 ステップ・期待結果が明記されたスクリプト形式
仕様書の有無 不要(テスター自身が判断) 仕様書がない状態からUIを解析して仕様書相当を逆生成

したがって Planner の正確な分類は、探索的テストの 手法(UIを動的に操作して情報を収集する)を使って、スクリプトテストの 仕様書 を生成する処理である。純粋な探索的テストでもスクリプトテストでもなく、両者の混合体と言える。

一方、Generator はテスト計画の各ステップを実際のブラウザ上でリアルタイムに実行するが、その動作は Planner が書いた計画を忠実にたどるものであり、新たな機能の発見や計画の修正は行わない。ステップ実行中に要素の特定方法を適応的に調整することはあるが(後述の dropdown の value 属性の発見等)、これは実装上の誤差修正であり、探索的テストの「学習」とは性質が異なる。

パイプライン全体は「探索的手法による仕様書生成(Planner)→ スクリプト化された実装(Generator)→ スクリプト化された回帰テスト(.spec.ts)」という変換プロセスである。

4.2 テスト技法の対応

JSTQB のテスト技法分類に対する対応状況を以下に示す。

ブラックボックス技法

技法 対応 根拠
同値分割法 暗黙的 "Edge cases and boundary conditions" という記述はあるが、同値クラスの定義手順はない
境界値分析 暗黙的 同上
デシジョンテーブル 非対応 条件組み合わせの体系的列挙を指示する記述がない
状態遷移テスト 暗黙的 "critical paths" "navigation paths" で部分的に該当するが、状態モデルの作成指示はない
ユースケーステスト 対応 "different user types" "Happy path scenarios" がユースケースベースの設計に該当

経験ベース技法

技法 対応 根拠
エラー推測 対応 Planner: "Error handling and validation" "negative testing scenarios"
探索的テスト プロセスのみ該当 Planner の情報収集プロセスは探索的だが、アウトプットはスクリプト仕様書であり、バグ発見を目的としない(4.1節参照)
チェックリストベースド 対応 Planner の出力がステップリスト形式であり、Generator がそれを入力として使用

ホワイトボックス技法(ステートメントテスト、デシジョンテスト)については、3エージェントのいずれもソースコードへのアクセス手段を持たないため対象外である。

ブラックボックス技法については「用語」は散見されるが「手法」としては体系化されていない。「Edge cases and boundary conditions」という記述はあるが、何に対する境界値か、同値クラスをどう定義するかの手順はない。LLM がこれらの用語を自発的に解釈して適用する可能性はあるが、体系的な適用は保証されない。

5. LLM への全面的依存

5.1 プログラムロジックの不在

3つのエージェント定義ファイルに含まれるプログラムロジックはゼロである。

構成要素 内容
.chatmode.md / agents/*.md 自然言語プロンプトのみ
.mcp.json 接続設定のみ
MCP ツール(Playwright 側) ブラウザ操作APIの提供。ただし「何を」「いつ」呼ぶかは LLM が決定

条件分岐、ループ制御、エラーハンドリングのいずれも LLM の推論に委ねられている。

5.2 Generator における LLM の介在

Generator のプロンプトには以下の記述がある。

For each step and verification in the scenario, do the following:

  • Use Playwright tool to manually execute it in real-time.

また公式ドキュメントには以下の記述がある。

It verifies selectors and assertions live as it performs the scenarios.

Generator は以下の4フェーズで動作する。

1. generator_setup_page
seed テストを実行してブラウザを初期状態にする

2. 各ステップのリアルタイム実行
LLM が browser_snapshot でページ構造を取得し、テスト計画のステップ文と要素をマッチングし、browser_click / browser_type 等の MCP ツールを呼び出す

3. generator_read_log
実行された全操作のログを取得する

4. generator_write_test
ログからテストコードを生成して書き出す

コード書き出し(4)の前にブラウザ操作(2)がある。つまり1回目の「テスト」は LLM が MCP ツール経由でブラウザを操作して実行する。生成された .spec.ts ファイルは以後 LLM なしで npx playwright test で繰り返し実行できる。

要素の特定は以下のように行われる。Planner が探索時に取得するページのアクセシビリティツリーは下記のような構造を持つ。

- search [ref=e31]:
  - combobox "検索" [active] [ref=e42]
  - button "Google 検索" [ref=e66]

テスト計画に「検索フィールドに 'playwright' と入力する」と記述されている場合、LLM はスナップショットの combobox "検索" をマッチング対象として選択し、browser_type ツールを ref=e42 に対して呼び出す。この操作がログに記録され、最終的に await page.getByRole('combobox', { name: '検索' }).fill('playwright') というコードに変換される。

5.3 ツール制約による責務分離

GitHub Copilot や Claude Code は汎用的なエージェントプラットフォームであり、ファイル編集、ターミナル実行、サブエージェント呼び出し等を自由に行える。Playwright Test Agents は tools: リストによってこの自由度を意図的に制限している。

Generator の tools: に含まれないもの:

機能 対応ツール 制限の意図
ファイル編集 edit/editFiles generator_write_test 経由でのみ書き出す
ターミナル実行 テスト実行は Generator の責務外
ネットワーク監視 browser_network_requests Planner / Healer のみ
スクリーンショット browser_take_screenshot Planner のみ

この制約により、Planner はコードを書けず、Generator は既存コードを修正できず、Healer は自由なブラウザ操作ができない。技術的には1つのエージェントで全工程を行うことも可能だが、3つに分離しているのは予測可能性とデバッグ容易性のための設計判断である。

6. テスト設計上の制約

6.1 seed テストによる起点制御

すべてのテストは seed テスト(tests/seed.spec.ts)の実行完了後のブラウザ状態から開始する。Planner は planner_setup_page、Generator は generator_setup_page を呼び出し、いずれも同じ seed テストを実行する。

seed テストには URL 遷移だけでなく、ログイン処理、テストデータ投入、Cookie 設定等を含められる。「何をテストの起点とするか」の制御は seed テストの記述に委ねられており、エージェント自身はそれを関知しない。

6.2 テストの独立性

Planner のプロンプトには以下の記述がある。

Assumptions about starting state (always assume blank/fresh state)
Ensure scenarios are independent and can be run in any order

全テストが同一の seed テストを起点とし、毎回同じ初期化処理を経て同じ状態から実行される。テスト間の状態引き継ぎ、テストチェーン、途中からの探索再開といった仕組みは存在しない。

Playwright 自体は storageState、Project dependencies、beforeAll 等の状態共有機構を持つが、エージェントのプロンプトはいずれも使用しない設計になっている。

この設計には LLM 固有の理由がある。テスト間で状態を引き継ぐ場合、LLM は「前のテスト実行後にどのような状態になったか」を正確に把握する必要があり、不確実性が掛け算で増大する。毎回 seed から始めれば、LLM は常に既知の初期状態だけを前提にすればよい。

6.3 MFA への対処

エージェントのプロンプトに MFA(多要素認証)への言及はない。MFA はブラウザ外の要素(SMS、認証アプリ等)を要求するため、MCP ツールだけでは対処できない。

対処はすべて seed テスト側で行う。テスト環境での MFA 無効化、storageState による認証状態の保存と再利用、API 経由でのトークン取得、TOTP の seed テスト内再現といったパターンが考えられるが、いずれもエージェントの設計範囲外であり、テスト設計者の責務となる。

7. JSTQB テストタイプとの対応

7.1 テストレベルとテストタイプ

JSTQB 分類 区分 Planner Generator Healer
テストレベル システムテスト 設計 実装・実行 修正・再実行
テストタイプ 機能テスト 対応 対応 対応
非機能テスト 限定的 限定的 限定的
変更関連テスト 対応
テスト技法 ブラックボックス 対応 対応 対応
ホワイトボックス 非対応 非対応 非対応

7.2 テストタイプ別の利用可能性

リファレンス(公式ドキュメント + プロンプト)から利用方法がどこまで読み取れるかを評価した。

テストタイプ 利用方法の明確度 備考
機能テスト 十分 パイプライン全体がこの用途向けに設計されている
ユーザビリティ 推測可能 Planner のロール定義に "user experience testing" があるが指示セクションに具体化されていない
性能テスト 不明 browser_evaluate で Performance API は叩けるが、その旨の案内はない
セキュリティテスト 不明 3ファイルすべてで記述なし
確認テスト 十分 Healer のワークフローとして明確に手順化されている
回帰テスト 推測可能 Healer が全テスト実行で失敗を検出するが運用ガイダンスはない

7.3 プロンプトとの整合性

Planner のロール定義には "functional testing, edge case identification, and comprehensive test coverage planning" と "user experience testing" が列挙されている。しかし指示セクション(手順1〜5)で具体化されているのは機能テストの範囲のみであり、ユーザビリティやアクセシビリティに関する手順は含まれていない。

また browser_network_requestsbrowser_console_messagesbrowser_evaluate といったツールは非機能テストに活用可能だが、どのプロンプトにも「いつ・どう使うか」の記述がない。ツールとしてのポテンシャルと、プロンプトでの指示の間にギャップがある。

8. LLM 依存の帰結

8.1 現時点の制約

アプリの複雑度 テスト計画の精度
単一ページ(Google 検索等) 問題なし
数画面の CRUD アプリ おそらく対応可能。一部の遷移を見落とす可能性あり
数十画面の業務アプリ 困難。コンテキストウィンドウの制約により探索途中で初期画面の記憶が失われる
iframe / Shadow DOM / 複雑な SPA 困難。スナップショットに要素が現れない場合がある

Generator のステップ解釈についても、テキスト入力のような単純操作は成功しやすいが、ドラッグ&ドロップや座標指定を要する操作では失敗しやすい。公式ドキュメントは "Generated tests may include initial errors that can be healed automatically by the healer agent" と述べており、Generator の出力が不完全になることは設計上の前提である。

8.2 再現性の問題

コードベースのテストフレームワークは同じ入力に対して同じ出力を返す。プロンプトベースの本設計では、同じテスト計画から同じテストコードが生成される保証がない。LLM の出力は確率的であり、テスト生成プロセス自体の再現性が不確定となる。

8.3 LLM の進化による影響

プロンプトベースの設計は、LLM の能力向上の恩恵を追加実装なしで受けられる。

LLM の進化 影響を受ける問題
コンテキストウィンドウの拡大 大規模アプリの探索で記憶が保持される
推論精度の向上 セレクタ選択の精度、ステップ解釈の正確性
マルチモーダル能力 視覚的 UI 要素の認識

一方、テスト対象アプリのサーバーサイドの状態制御、ネットワーク遅延、MFA のようなブラウザ外の要素、テスト環境の構築については、LLM の能力向上では改善されない。

また、プロンプトに「状態遷移図を作成せよ」「同値分割を適用せよ」といったテスト設計技法の指示を追加することで、現在は体系化されていないブラックボックス技法を適用できる可能性がある。ただし、それが実際に機能するかは LLM の能力に依存する。

9. 実行検証: the-internet.herokuapp.com での実測

前節までの分析を検証するため、https://the-internet.herokuapp.com/ を対象に3エージェントのパイプラインを実行した。このサイトは Dave Haeffner が作成したテスト自動化練習サイトで、40以上の Web UI パターンを収録しており、多様なインタラクションを持つ点で検証対象として適切である。

サイトには44ページのテスト対象が存在するが、時間的な都合もありシナリオを絞って作成するよにプロンプトで指示してテストを作成させた。テストエージェントは6シナリオについて21テストを作成した。

9.1 パイプラインの実行結果

Phase エージェント 入力 出力 結果
計画 Planner seed テスト(トップページへの遷移) specs/the-internet.md(782行、12シナリオ、48テストケース) 成功
実装 Generator 計画から6シナリオを選択 6ファイル、20テスト 成功(MCP 直接操作)
初回実行 21テスト(20 + seed) 19 passed / 2 failed Dynamic Loading でタイムアウト
修正 Healer 失敗した2テスト toBeVisible({ timeout: 10000 }) 成功
再実行 21テスト 21 passed (16.8s) 全テスト通過

9.2 Generator のロケーター選択過程

Generator がアクセシビリティツリーから Playwright ロケーターを生成する過程を観察できた。

スナップショット上の要素 生成されたロケーター 方針
textbox "Username" [ref=e16] page.getByRole('textbox', { name: 'Username' }) ARIA ロール
button "Click for JS Alert" [ref=e12] page.getByRole('button', { name: 'Click for JS Alert' }) ARIA ロール
combobox [ref=e9] page.locator('#dropdown') CSS ID(名前なし要素の場合)
img "User Avatar" [ref=e11] page.getByRole('img', { name: 'User Avatar' }).first() ロール + nth

ARIA ロールとアクセシブルネームの組み合わせが第一選択肢であり、名前がない要素では CSS セレクタにフォールバックする。これは Playwright 公式が推奨するロケーター戦略と一致している。

9.3 Healer の修正内容

Dynamic Loading のテストは、「Start」ボタンクリック後のローディングが約5秒かかるのに対し、toBeVisible() のデフォルトタイムアウトが5秒であるため失敗した。Healer は原因を正確に特定し、タイムアウトを10秒に延長した。

- await expect(page.getByText('Hello World!')).toBeVisible();
+ await expect(page.getByText('Hello World!')).toBeVisible({ timeout: 10000 });

waitForTimeout() のような非推奨パターンではなく、アサーションのタイムアウト延長という Playwright のベストプラクティスに沿った修正であった。

9.4 実行から見えた設計の裏付け

記事の分析と一致した点:

  • 毎回 generator_setup_page で seed テストが実行され、ブラウザが初期化された(セクション6.2 テストの独立性)
  • Generator はテスト計画のステップをリアルタイムにブラウザで実行し、その記録からコードを生成した(セクション5.2 の「Read & Execute & Record」)
  • MCP ツールのパラメータを正しく指定する必要があり、LLM の判断が介在していた(セクション5.1 の LLM 依存)
  • JS ダイアログ処理では browser_handle_dialog はダイアログが存在する状態でのみ呼べるという制約があり、LLM がその順序を正しく判断する必要があった

新たに判明した点:

  • Generator サブエージェントとして起動した場合、MCP ツールへのアクセスが確保されない場合がある(プラットフォーム側の制約)
  • generator_write_test はコード書き出し前に seed テストを実行して検証する仕組みを持っており、書き出しの成否が確認される
  • dropdown の value がテキスト表示値("Option 1")ではなく HTML の value 属性("1")であることを LLM が実行時に発見し対応できた

10. 所見

Playwright Test Agents は、仕様書がない状態から LLM が UI を探索的に解析してテスト仕様書を逆生成し、それをスクリプト化された回帰テスト(.spec.ts)に変換するパイプラインである。エージェント定義ファイルにプログラムロジックは一切含まれず、テスト設計の判断、ブラウザ操作の選択、テストコードの生成のすべてが LLM の推論に委ねられている。

Planner のプロセスは JSTQB の探索的テストの定義(設計・実行・記録・学習の同時進行)に合致するが、そのアウトプットはスクリプトテストの仕様書である。Planner 自身がバグを発見することはなく、純粋な探索的テストとは言えない。正確には「探索的手法によるテスト仕様書の自動生成」であり、Generator は計画の忠実な実装者、生成された .spec.ts は LLM なしで繰り返し実行可能な回帰テストである。the-internet.herokuapp.com での実測では、Planner が12シナリオ・48テストケースの計画を生成し、Generator が20テストを実装し、Healer がタイムアウトの問題を修正して全テストを通過させた。Generator が計画を逸脱して新たな機能を発見する場面はなく、Planner と Generator の役割分離は設計通りに機能していた。

この設計は「現在の LLM の能力でできる範囲を、最小の仕組みで最大限活用する」というプラグマティックな判断であり、LLM の進化を前提とした設計でもある。プロンプトを変えるだけで新しいテスト技法を適用できる拡張性を持つ一方で、LLM の能力の天井がフレームワークの天井となる構造的制約を内在している。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?