ai-test-generation について
テストチーム向けに、要件からレビュー可能なテストを作るスキルです。コード生成の前にリスク分析、カバレッジ表、アサーション用オラクルを作成し、生成後の人によるレビューも必須とします。
主な機能
- 01仕様、バグ報告、コードからルールを抽出
- 02リスク、不変条件、曖昧さを分析
- 03要件とテストシナリオを対応付け
- 04シナリオとオラクル設計を分離
- 05追跡可能なテストコードを生成
- 06生成テストの人によるレビューを必須化
活用シーン
- 01PRD やユーザーストーリーからテストを計画
- 02コード変更の回帰シナリオを作成
- 03バグ報告から検証テストを作成
- 04API スキーマからカバレッジシナリオを導出
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ petrkindlmann/ qa-skills --skill ai-test-generationインストール後、Claude Code で/ai-test-generationを入力して読み込まれたか確認します。
同梱ファイルreferences/prompt-patterns.md
詳細
開始前に: プロジェクトルートに .agents/qa-project-context.md があるか確認してください。このファイルには技術スタック、テストフレームワーク、命名規則、セレクター戦略、既知のリスク領域が記載されており、生成されるテストの品質を大きく高めます。
クイックルート
入力の種類が何であっても、パイプラインは同じです。変わるのはステップ1で抽出する内容だけです。該当する行を確認し、その後はステップ2~7を変更せずに実行してください。
| 入力の種類 | ステップ1で抽出する内容 | 注意点 |
|---|---|---|
| PRD/機能仕様 | エンティティ、ビジネスルール、受け入れ基準、NFR、明示された前提条件 | 「シームレス」「高速」といった表現から推測される暗黙の要件 |
| ユーザーストーリー+AC | 各AC → 1つ以上の正常系シナリオ+1つ以上の異常系シナリオ | 1行に複数の振る舞いが隠れているAC |
コード差分(git diff main...HEAD) | 新規/変更されたコードパス、変更された条件分岐、削除された振る舞い | 回帰テストの範囲:モジュール全体ではなく、変更されたパスをテストする |
| バグ報告 | 再現手順、期待値と実際の結果、環境 | 期待値を検証するテストを作成してください。現時点では失敗し、修正後に成功するテストです |
| OpenAPI/GraphQL SDL | エンドポイント、スキーマ、必須フィールド、列挙型、認証 | 200応答だけでなく、エンドポイントごとのバリデーション、認証失敗、エッジケース |
Playwright プロジェクトでは、エージェント統合モードも選択してください。詳しくは「ディスカバリーの質問」の Q2 を参照してください。
ディスカバリーの質問
まず .agents/qa-project-context.md を確認してください。ファイルが存在する場合はその内容を使い、すでに回答済みの項目は省略してください。その後、以下を確認します。
-
入力元は何ですか? PRD/仕様、ユーザーストーリー+AC、コード差分、バグ報告、API スキーマのいずれかです。ステップ1で何を重点的に抽出するかが決まります(「クイックルート」を参照)。LLM/AI 機能の仕様の場合はここで止めてください。Playwright の仕様ではなく、
ai-system-testingで評価用データセットを生成してください。 -
対象のテストフレームワークは何ですか? また、Playwright の場合はどのエージェント統合モードを使いますか?
- E2E: Playwright(推奨)、Cypress。ユニット: Jest、Vitest、pytest。API: Playwright の
APIRequestContext、Supertest、requests。 - Playwright CLI+エージェント(Claude Code/Codex/Cursor に推奨):
npx playwright init-agents --loop=claudeは、プランナー/ジェネレーター/ヒーラーの各エージェントを.claude/agents/に Markdown として生成します。これらは対話型の開発ツールであり、CI でそのまま実行できる標準的な Playwright テストを生成します。トークン効率が高く、エージェントのループ内で動作します。 - Playwright MCP(
npx @playwright/mcp@latest):より高いオーバーヘッドが発生しますが、エージェントが長時間のセッションにわたって、ライブブラウザーを対話的に操作する必要がある場合に適しています。 - どちらも使わない — AI を補助的な作業用ツールとして使い、テストを手動で作成します。
- E2E: Playwright(推奨)、Cypress。ユニット: Jest、Vitest、pytest。API: Playwright の
-
利用できるプロジェクトコンテキストは何ですか? 既存のテストパターン、Page Objects/ヘルパー、データファクトリー/フィクスチャ、CI の制約(タイムアウト、並列実行など)を確認してください。コンテキストが多いほど、後処理が少なくなります。
-
レビューのワークフローはどうしますか? パイプライン全体の実行 → 人によるレビュー → マージ(デフォルト)、シナリオのみを生成してコードは人が作成、またはコードを生成して人が反復的に調整する方法があります。
-
必要なドメイン知識は何ですか? 規制対象業界(医療、金融)でのコンプライアンス、ドメイン不変条件(金額は常に0以上、予約は重複しないなど)、過去のインシデントから判明しているリスク領域を確認してください。
基本原則
-
コードより先にパイプラインを実行します。 何を、なぜ、どのように検証するのかを明確にする前に、テストコードを生成してはいけません。7段階のパイプラインは、誤った対象に向けてコードを早まって生成するのを防ぐためにあります。
-
構造化された中間成果物こそが成果物です。 前提条件ドキュメント、カバレッジマトリックス、オラクルの定義は、テストコードそのものより価値があります。レビュー可能で、追跡可能であり、再利用できます。
-
何をするかと、どのように行うかを分けます。 シナリオ生成(何をテストするか)とオラクル設計(どのように検証するか)は、異なる思考作業です。これらを混ぜると、アサートしやすい内容に偏ったシナリオができ、アサーションは後付けになります。
-
AI が初稿を生成し、人間がレビューして改善します。 人間のレビューなしに、AI が生成したテストをリリースしてはいけません。AI は作業を加速しますが、判断を置き換えるものではありません。
-
コンテキストがすべてです。 LLM に、規約、既存のパターン、セレクター戦略、データのセットアップを提供してください。コンテキストが多いほど、後処理が少なくなります。
-
量より質を重視します。 各テストには保守コストがかかります。テスト数ではなく、重要な経路、複雑なロジック、既知のリスク領域に焦点を当ててください。
パイプライン
必須のワークフロー — エージェントは必ず次の順序に従ってください:
Step 1: Extract → Requirements, entities, business rules from input
Step 2: Analyze → Risks, invariants, edge cases, ambiguities
Step 3: Map → Coverage matrix (requirement → scenario → priority)
Step 4: Generate → Candidate scenarios (happy + boundary + negative + security + a11y)
Step 5: Design → Assertions and oracles SEPARATELY from scenarios
Step 6: Code → Test code (only after all above exist)
Step 7: Review → Human review with traceability back to source
各ステップ(抽出、リスク分析、シナリオ、オラクル、コード)の完全なプロンプトテンプレートは、references/prompt-patterns.md にあります。以下に各ステップの出力形式を示します。
ステップ 1:要件とエンティティを抽出する
入力を構造化された要素に分解します:エンティティ(役割/状態/属性を含む)、ビジネスルール(番号付き)、明示的な要件([REQ-N]、ソースに記載)、暗黙的な要件([IMP-N]、推論したもの — すべて人間の確認が必要なものとして明示)。明示的な要件と推論した要件を分けることが、前提条件を仕様であるかのようにテストするのを防ぐルールです。
ステップ 2:リスク分析と不変条件
発生しうる問題、常に成立しなければならないこと、ソースに記載がない箇所を導き出します。
- リスク —
Risk | Likelihood | Impact | Source Requirementの表(例:在庫数を減らす際の競合状態、メールの遅延が 30 秒を超える)。 - 不変条件(常に成立しなければならない条件)—
stock >= 0、order total = sum(items) + tax + shipping、user sees only their own orders。 - 曖昧な点(人間の回答が必要)—「送料無料は割引コードの適用前と適用後のどちらに適用されますか?」これらを明示的に記録し、黙って一方を選んではいけません。
- リスクから導かれるエッジケース — 2 人のユーザーが最後の 1 個を購入する、決済は成功したがメールサービスが停止している。
ステップ 3:カバレッジマトリックス
最も重要な成果物です。抜け漏れと重複の両方を防ぎます。すべての要件を、カテゴリ、優先度、オラクルの種類を付けたシナリオに対応付けます。
| 要件 | シナリオ | カテゴリ | 優先度 | オラクルの種類 |
|---|---|---|---|---|
| REQ-1 | 空のカートに商品を 1 つ追加する | 正常系 | P0 | 状態:カート内の商品数 = 1 |
| REQ-1 | 在庫切れの商品を追加する | 異常系 | P0 | UI:エラーメッセージ、カートに変更なし |
| REQ-2 | 有効なカードでチェックアウトを完了する | 正常系 | P0 | 状態:注文が作成され、在庫数が減少 |
| REQ-2 | 2 人のユーザーが最後の 1 個を同時にチェックアウトする | 競合状態 | P1 | 1 人は成功し、もう 1 人には在庫エラーが返る |
| INV-1 | 在庫数が決してマイナスにならない | 不変条件 | P0 | データ:どの操作後も stock >= 0 |
作成後、次の点を確認します。すべての要件に 1 つ以上の正常系シナリオと 1 つ以上の異常系シナリオがあること、すべての不変条件に直接テストがあること、ステップ 2 のすべてのリスクにシナリオがあること、同じ内容をテストする行が 2 つないこと。
ステップ 4:候補シナリオを作成する
マトリックスの各行について、明示的なテストデータ要件を含めて、Given/When/Then 形式でシナリオを完全に記述します(Given: カートに99個の商品があるユーザー(上限100個);When: さらに1個追加する;Then: 個数 = 100)。次のカテゴリを体系的に網羅します。
| カテゴリ | 説明 |
|---|---|
| ハッピーパス | ユーザーが機能の想定どおりに操作する |
| 境界値 | 有効な入力範囲の端。BOUNDARIES フレームワーク(references/prompt-patterns.md)を使用します |
| ネガティブ | 無効な入力、権限のない操作 |
| セキュリティ | 認証の回避、インジェクション、権限昇格 |
| アクセシビリティ | スクリーンリーダー、キーボードのみの操作、コントラスト |
| 状態遷移 | 状態間の有効および無効な遷移 |
| 並行性 | 2人のユーザーが同時に操作する |
ステップ 5:アサーションとオラクルを設計する
ステップ 4 とは明確に分けてください。 シナリオは振る舞いを記述し、オラクルはその検証方法を記述します。各シナリオについて、カテゴリごとにオラクルを定義します。1つのアサーションだけで振る舞いを証明できることはほとんどありません。
| オラクルのカテゴリ | 検証する内容 | 例 |
|---|---|---|
| UI の状態 | 表示されるテキスト/要素の状態 | cart badge toHaveText('1') |
| データ | API/DB 経由で永続化された状態 | GET /api/cart が商品1個と正しい合計金額を返す |
| ネガティブ | 起きてはならないこと | エラートーストが表示されない;別ページに遷移しない |
| 副作用 | 非同期/外部の結果 | アナリティクスの add_to_cart が発火する;30秒以内にメールが受信トレイに届く |
オラクルの品質ルール: 実装の詳細ではなく、ビジネス上の結果をアサートします。利用可能な中で最も具体的なアサーションを使用します(toBeTruthy() ではなく toHaveText('$29.99'))。ネガティブアサーションを含めます。UI だけでなくデータの整合性を検証します。アクセシビリティ(フォーカス管理、ライブリージョンの通知)をアサートします。
ステップ 6:テストコードを生成する
ステップ 1〜5でレビュー済みの成果物が作成された後にのみ実施します。 コードは、要件とシナリオにさかのぼれるコメントを付けて、シナリオとオラクルをフレームワークの構文に機械的に変換したものです。
/**
* Scenario: SC-001 — Add single item to empty cart
* Requirement: REQ-1 (User can add items to cart)
* Priority: P0
*/
test('add single item to empty cart', async ({ page, testProduct }) => {
await page.goto(`/products/${testProduct.id}`); // Given
await page.getByRole('button', { name: 'Add to cart' }).click(); // When
await expect(page.getByTestId('cart-badge')).toHaveText('1'); // Then
await expect(page.getByTestId('error-toast')).not.toBeVisible(); // Negative oracle
});
コード生成ルール: プロジェクトの規約(qa-project-context.md から)に合わせます。既存の Page Objects、フィクスチャ、データファクトリーを再利用します。トレーサビリティコメント(Scenario: SC-XXX、Requirement: REQ-XX)を含めます。プロジェクトのセレクター戦略に従います。セットアップとティアダウンはインラインではなく、フィクスチャに記述します。
ステップ 7:人間によるレビュー
任意ではなく、必須のパイプラインステップです。これは、マージ前にこのパイプラインで生成したテストをレビューします。直前に生成したものではない既存のテストスイートを監査する場合は、代わりに ai-qa-review を使用してください。生成した各テストを、次のチェックリストですべて確認します。
- 要件まで追跡できる: テスト → シナリオ → カバレッジの行 → 要件をたどれる。
- 実装ではなく振る舞いをテストしている: 無害なリファクタリング後もテストが通る。
- 抽象化レベルが適切: テストの種類(ユニット/統合/E2E)が適切である。
- テストの命名と読みやすさ: テスト名が振る舞いを示している。本文を読み解かなくても、読者が意図を理解できる。
- テストの分離/共有状態がない: テストが独自のデータを作成して後片付けし、兄弟テストとの実行順序に依存せず、単独または任意の順序で実行しても成功する。
- 現実的なテストデータ: 妥当で多様なデータを使用し、
example.comを使用している。 - 意味のあるアサーション: オラクルの定義に一致し、具体的であり、
toBeTruthy()を使用していない。 - プロジェクトの規約に合致している: 命名、構造、セレクター戦略。
- 不安定になるリスクがない: ハードコードされたタイムアウト、競合状態、実行順序への依存がない。
- エッジケースを含んでいる: ハッピーパスにとどまらない。
- 前提条件が検証されている: コーディング前にステップ2の曖昧な点が解決されている。
テストごとのレビュー結果: KEEP(そのままマージ)・MODIFY(指摘された問題を修正してからマージ)・REJECT(要件の誤り、抽象化の誤り、存在しない API の捏造)・DEFER(曖昧な点の解決待ち)。
ガードレール
厳守事項です。エージェントは必ず従ってください。
- カバレッジの前にコードを書くことは禁止です。 ステップ 1~3(要件、前提を明記したリスク分析、カバレッジマトリクス)が揃う前に、テストコードを出力してはいけません。エージェントがコード作成に進んでしまった場合は、停止して戻ってください。
- 実装ではなく結果を検証してください。
expect(screen.getByRole('progressbar')).toBeVisible()を使い、expect(component.state.isLoading).toBe(true)は使わないでください。expect(page.getByTestId('cart-badge')).toHaveText('1')を使い、expect(store.dispatch).toHaveBeenCalledWith(...)は使わないでください。 - 必ず、オラクルより先にシナリオ(ステップ 4)を作成してください。 シナリオは「何が起きるか」、オラクルは「どう検証するか」です。これらを混在させると、シナリオが簡単にアサーションできる内容に偏ります。
- 中間成果物を必ずすべて作成してください — 前提ドキュメント、未解決の曖昧さ、オラクル候補、トレーサビリティチェーンを、簡略版でも作成してください。
検出した場合は、以下を指摘してください。
- 幻覚による API — コードベースに存在しないエンドポイント、セレクター、メソッド、インポートです。人によるレビューの前に、機械的に検証してください(「検証」を参照)。
- 重複したシナリオ — 挙動が同じで、データだけがわずかに異なるものです。統合するか、パラメーター化してください。
- 価値の低いアサーション —
expect(response).toBeTruthy()、expect(page).toHaveURL(/.*/)などです。 - ネガティブケースの不足 — すべてのシナリオがハッピーパスの場合、カバレッジマトリクスは不完全です。
- 非現実的なテストデータ —
[email protected]、John Doe、password123などです。example.comを使い、多様で妥当なデータを用意してください。
ステップごとのモデル選択
慣習ではなく、難易度に応じてモデルを使い分けてください。機械的な抽出(ステップ 1)とカバレッジマトリクスの整理(ステップ 3)には、低コストのモデルで十分です — Haiku 4.5 または Sonnet 4.6 で十分です。推論を誤るとコストがかかるオラクル設計(ステップ 5)と、幻覚に特に注意が必要なコード生成(ステップ 6)には、Opus 4.8 を使ってください。真に難しい推論(微妙な不変条件、規制対象領域のロジック)に限り、Fable 5 を選んでください。すべてのステップで最も強力なモデルを使うのは無駄です。一方、ステップ 6 で最も安価なモデルを使うと、存在しない API が作り出されます。
検証
「幻覚による API」への警告を、機械的なゲートにしてください。ステップ 6 の後、人によるレビューの前に、次を実行します。
- インポートと型を解決します。 TypeScript の場合:
npx tsc --noEmit— 作り出されたインポートや誤ったシグネチャは、ここでエラーになります。Python の場合:python -m pyflakes <files>またはruff checkを実行します。 - 生成されたセレクター/エンドポイントをコードベースと照合して grep します。 すべての
getByTestId('...')の ID と、テストから呼び出すすべての API パスがソースに実在することを確認してください。grep -roE "getByTestId\('([^']+)'\)" generated/ | sed -E "s/.*'([^']+)'.*/\1/" | sort -u \ | while read id; do grep -rq "$id" src/ || echo "MISSING testid: $id"; done - テストスイートを一度実行します。 存在しないルートやセレクターを参照するテストはすぐに失敗します。レビュー前にそれらを隔離し、デッドコードをレビューしないようにしてください。
MISSING の行や tsc エラーは、担当者がレビューに時間を費やす前に修正すべき幻覚です。
アンチパターン
- いきなりコードを書く。 最もよくある失敗です。エージェントはPRDを受け取ると、すぐにテストを書き始めます。カバレッジマトリクスがなければ、シナリオを見落としたり、重複したシナリオを追加したりします。このパイプラインは、そうした事態を防ぐためにあります。
- 振る舞いではなく実装を検証する。
expect(component.state.isLoading).toBe(true)は、リファクタリングのたびに壊れます。ユーザーが観察するものを検証するため、expect(screen.getByRole('progressbar')).toBeVisible()をアサートしてください。 - シナリオとアサーションを混在させる。 「この機能をテストして、この値を確認する」と、1つのステップにまとめて書くことです。何をテストするかとどう検証するかを分けてください。
- プロンプトにプロジェクトのコンテキストを含めない。 規約や既存のパターンがなければ、一般的なテストが生成されます。まさにそのために
qa-project-context.mdがあります。 - 過剰に生成する。 AIは、単純な関数に対して50個のテストを書くことがあります。テストにはそれぞれメンテナンスコストがかかります。カバレッジマトリクスを使って、生成対象を意味のあるシナリオに限定してください。
- 理解せずにコピー&ペーストする。 生成されたテストが何をするのか、なぜそうするのか説明できない場合は、マージしないでください。理解していないテストは、デバッグできないテストになります。
- レビューせずにリリースする。 ステップ7は任意ではありません。AIが生成するテストには、幻覚によるAPI、誤ったセレクターやビジネスロジック、フレークが日常的に含まれており、人間のレビューでしか見つけられません。
- フィードバックループを無視する。 AIのテストが実際のバグを見つけたら、効果のあったプロンプトのパターンを記録してください。誤検知が起きたら、何が問題だったかを記録してください。プロジェクト固有の、効果があった方法のライブラリを構築しましょう。
完了条件
- 7つすべての成果物がそろっていること:要件ドキュメント、リスクと不変条件、カバレッジマトリクス、シナリオセット、オラクル定義、テストコード、およびテストごとのKEEP/MODIFY/REJECT/DEFERの判定を含むレビューノート。
- テストコードファイルを1つでも書く前に、カバレッジマトリクスを作成し、レビューしていること。
- 検証に合格していること:
tsc --noEmit(または言語に相当するコマンド)が終了コード0で終了し、セレクター/エンドポイントのgrepでMISSINGの行が0件であること。 - 生成された各テストに、人間によるレビュー判定が記録されていること。レビュー判定がないテストにKEEPが付いていないこと。
- スイートのCIジョブが終了コード0で終了していること(グリーン)。
- 再現性メタデータを記録していること:正確なモデルID(例:
claude-opus-4-8、claude-sonnet-4-6、claude-haiku-4-5-20251001)、入力ソースのハッシュ、そして呼び出した各スキル/CLI/MCP サーバーのバージョン。
関連スキル
- qa-project-context — AIによるテスト生成の品質を大幅に高めるコンテキストファイルを設定します。最初に設定してください。
- playwright-automation — Playwrightの詳細なパターン(POM、フィクスチャ、CI)に加え、テストエージェント(
init-agents --loop=claude。.claude/agents/に生成されます)と、Discovery Q2で選択した@playwright/mcpのモードを扱います。生成されたテストは、このフレームワーク内に置かれます。 - unit-testing — ユニットレベルで生成されたテスト向けのJest、Vitest、pytestのパターン。
- api-testing — OpenAPI仕様から生成したテスト向けのエンドポイントテストパターン。
- test-strategy — 生成する前に、何をどのレベルでテストするかを決めます。
- test-reliability — 生成されたテストの信頼性を高めます:フレークの分類、修復、動画による証跡。
- ai-system-testing — 入力がLLM機能の仕様の場合、Playwrightの仕様ではなく、こちらで評価データセット(Promptfoo、DeepEval、Ragas、Braintrust)を生成します。
- ai-qa-review — 自分が生成したものではない既存のスイートを監査します(テストの臭い、テスト容易性)。ここでのステップ7では、このパイプライン自身の出力だけをレビューします。
- ai-bug-triage — 生成されたテストでバグが見つかった場合、トリアージパイプラインを通じて分類・報告します。
参考ファイル(references/ 内)
- prompt-patterns.md — 7つのステップに対応するプロンプトの完全なライブラリです。抽出、リスク分析、シナリオ生成、オラクル設計、コード生成の各プロンプトに加え、ステップ4で使用するBOUNDARIESエッジケースフレームワークが含まれます。