現在の実装ではなく製品の意図からテストを生成するには?

ほとんどのテスト生成は、間違った出発点から始まっている。
それはコードから始まる。ツールがソースファイルを読み込み、関数シグネチャをトレースし、コンポーネントツリーを検査し、現在の実装が行っていることに基づいてアサーションを生成する。テストは技術的に根拠があり、現在存在するバグも含め、今この瞬間の製品を反映している。
これが問題だ。実装から導出されたテストは、製品が正しいかどうかを検証しない。製品が自分自身と一貫しているかどうかを検証するだけだ。実装にバグがあれば、テストはそのバグを期待される動作としてコード化する。テストスイートはグリーンになる。バグはリリースされる。テストは設計通りに機能したが、それでも役に立たなかった。
製品の意図からテストを生成することは、根本的に異なるアプローチだ。現在のコードが生み出す結果に関係なく、製品が何をすべきかにテストの目標を基づかせることを意味する。その方法を説明しよう。
実装から導出されたテストがなぜその役割を果たせないかを理解する
アプローチを変える前に、実装から導出されたテストがすぐには明らかでない形で失敗する理由を正確に理解しておくことが重要だ。
エンジニアがコードを読んでテストを書くとき、彼らは「このコードは何をしているか?」と問い、その動作を検証するアサーションを書く。その問いは正しそうに見える。しかし、それは間違った問いだ。
正しい問いは「この製品はユーザーに対して何をすべきか?」だ。この二つの問いは異なるテストを生み出し、実装と意図された動作が乖離するたびにその差が重要になる。
具体的な失敗例を示そう。AIコーディングエージェントがチェックアウトフローを生成する。実装にバグがある:割引コードが税額計算の後ではなく前に適用されており、不正な合計金額が算出される。コードから導出されたテストは実装を読み、処理の順序を確認し、割引が税額計算前に適用されることをアサートする。テストはパスする。バグは正しい動作としてコード化される。以後、偶然バグを修正するような変更を加えるとテストが失敗し、エンジニアは元の動作が誤りだったことに気づかないまま、新しい実装に合わせてテストを更新してしまう。
意図から導出されたテストは、ユーザーが観察できる成果に基づいている:最終的な合計金額は、税額計算後の金額に割引を適用した結果を反映すべきだ。実装の順序が誤っていれば、実装が変わったからではなく、結果が誤っているためにテストが失敗する。
ステップ1:意図と実装を分離する
最初の実践的なステップは、コードとは独立して存在する製品の意図の唯一の情報源を確立することだ。
チームがPRD、ユーザーストーリー、または受け入れ基準を使用しているなら、それらのドキュメントが意図のレイヤーとなる。コードがどのように実現するかではなく、ユーザーの視点から製品が何をすべきかを記述している。それらのドキュメントに基づいたテストスイートは、定義上、意図に基づいている。
チームに正式なドキュメントがない場合、つまり多くの初期段階やAIネイティブなチームが素早くリリースしている状況では、意図はそれでも存在する。元の設計判断、機能目標、ユーザーが何を達成できるべきかというメンタルモデルの中に存在する。課題は、その暗黙の意図をテスト生成の基準となるほど明示的にすることだ。
TestSpriteはどちらのケースにも対応する。
PRDや仕様書が存在する場合、TestSpriteはそれを解析し、ドキュメントから製品の意図の構造化モデルを構築する。テストの目標は、現在のコードが生み出す結果ではなく、仕様書が製品に求めていることに基づいている。
PRDが存在しない場合、TestSpriteのMCPサーバーはコードベースから直接製品の意図をリバースエンジニアリングする。関数の戻り値を読んでアサーションを立てるのではなく、ルート定義、APIコントラクト、コンポーネント構造、命名規則を、製品が何を実現するために設計されたかを示す根拠として扱う。その結果、実装ではなく意図を捉えた構造化された内部PRDが生成される。
どちらの場合も、テスト生成プロセスは現在のコードの状態ではなく、意図から始まる。
ステップ2:コードレイヤーではなく製品レイヤーでテストする
適切な出発点を持つことは重要です。そして、適切なレイヤーでテストすることも同様です。
明確なインテントドキュメントがあっても、コードレイヤーのテストツールはそのインテントを実装アサーションに変換します。PRDを読み込み、関連コンポーネントを特定し、それらのコンポーネントがコードと整合した動作をするかを検証するテストを生成します。インテントに基づく根拠付けは有効ですが、検証はやはりコードレイヤーで行われます。
プロダクトインテントからテストするには、プロダクトレイヤー、つまり実際の条件下で実ユーザーの操作を伴って動作する実アプリケーションで検証する必要があります。
他の検証ツールはコードを読んで推測します。TestSpriteはあなたのアプリを開いて実際に使います。
Claude Code、Cursor、Windsurf、またはMCP対応のAI IDEにおけるTestSprite MCPサーバーを通じて、単一の命令でインテントに基づくテストパイプラインが起動します。
「TestSpriteでこのプロジェクトをテストしてください。」
並列探索エージェントの群がライブアプリケーションを訪問し、実ユーザーと同じようにナビゲートします。テスト対象を把握するためにソースファイルを読み込むことはありません。プロダクトを実際に使用して何ができるかを発見し、インテントモデルが定めるべき動作と比較します。
ステップ3:エージェントにギャップを発見させる
インテントに基づくテストの最も価値ある成果は、テスト自体ではありません。プロダクトの動作がプロダクトインテントから乖離している箇所を発見することです。
探索エージェントがインテントモデルを念頭に置きながらライブアプリケーションをナビゲートするとき、まさにそうした乖離を探しています。ユーザーストーリーには、Viewerロールのユーザーはレコードを削除できないと記載されています。エージェントはViewerとしてログインし、該当セクションに移動し、UIレイヤーとAPIレイヤーの両方で削除操作を試みます。フロントエンドが削除ボタンを正しく非表示にしているにもかかわらず、APIが削除リクエストを受け付けてしまった場合、それはインテントと実装の乖離です。これは即座に表面化します。
ユーザーストーリーには、購入完了時に正しい注文合計金額を含む確認画面が表示されるべきと記載されています。エージェントはカートに商品を追加し、割引コードを適用し、チェックアウトを完了し、確認画面を確認します。表示された合計金額が期待される計算結果と一致しない場合、それが乖離です。コードレベルのアサーション失敗ではありません。ユーザー視点の言葉で記述された、プロダクトの動作失敗です。
これが、インテントから導出されたテストが実装から導出されたテストでは見逃すバグを検出できる理由です。実装は内部的に一貫しています。しかし実装とインテントは一致していません。そしてテストはインテントに紐付けられています。
ステップ4:バックエンドのインテントもカバーする
プロダクトインテントはAPIレイヤーにも及びます。すべてのAPIコントラクトは暗黙のインテントを表しています。つまり、このエンドポイントはこれらの入力を受け付け、これらの条件下でこれらの出力を返すべきであるということです。
APIのコードインスペクションからテストを導出すると、APIが現在行っていることをアサートします。APIインテントからテストを導出すると、APIが行うべきことをアサートし、そのインテントからの逸脱を検出します。
TestSpriteのバックエンドテスティング2.0は、コードインスペクションではなく事前観測によってこれをカバーします。APIテスト計画を生成する前に、エージェントがエンドポイントを呼び出し、実際のレスポンスを観測します。その観測された動作がベースラインとなり、APIの実際のコントラクトを表します。以降の実行では、新しい動作をそのベースラインと比較します。
AIコーディングエージェントがバックエンドを変更し、エンドポイントの返す内容をサイレントに変更した場合、次のテスト実行でそれが確立されたコントラクトからの逸脱として検出されます。以前は`user_id`として返されていたフィールドが`userId`として返されるようになった場合は破壊的変更であり、具体的で対処可能な失敗として表面化されます。
実際のレスポンスからの動的変数は、マルチステップAPIシーケンスを通じて自動的に受け渡されます。createエンドポイントが実際のIDを返し、そのIDがread、update、deleteのステップに渡されます。ライフサイクル全体が、コードインスペクションから書かれた静的アサーションに対してではなく、APIサーフェスの実際のインテントに対して実行されます。
ステップ5:失敗をコーディングエージェントにフィードバックする
インテントに基づくテストは、完全なループを閉じることで最も強力になります。
プロダクトの動作がプロダクトインテントから乖離したためにテストが失敗した場合、その失敗はコーディングエージェントが直接対処できる形で開発環境に返される必要があります。スタックトレースやアサーションエラーではなく、どのユーザー操作が行われたか、プロダクトインテントが何を要求していたか、そしてプロダクトが実際に何を提供したかの説明です。
TestSpriteはまさにこの目的のために失敗情報を構造化します。失敗の説明は、Claude Code、Cursor、またはWindsurfが動作しているIDEに、コーディングエージェントが読み取り対処できる形式で返されます。エージェントはインテントと動作のギャップに基づいて修正を提案します。その修正は同じセッション内でレビューおよび適用されます。
インテントからテスト、失敗、修正へと至るループは開発ワークフロー内で完結します。ダッシュボードの切り替えは不要です。コードレベルのアサーション失敗をプロダクトレベルの動作問題に結びつけるための手動調査も不要です。
GitHub Actionsとの統合により、このループがCIに拡張されます。すべてのプルリクエストがライブアプリケーションに対するインテントに基づく検証をトリガーします。結果はPRコメントとして投稿されます。インテント違反はコードがマージされる前に表面化されます。
まとめ
現在の実装ではなくプロダクトインテントからテストを生成するには、3つのことが必要です。コードとは独立して存在するインテントの信頼できる情報源、コードレイヤーではなくプロダクトレイヤーで検証するテストアプローチ、そして実装の言葉ではなくインテントの言葉で失敗を記述するフィードバックループです。
TestSpriteはこの3つすべてを提供します。PRDが存在する場合はそれを解析し、存在しない場合はコードベースからインテントをリバースエンジニアリングします。探索エージェントは実ユーザーのようにライブアプリケーションをナビゲートし、観測された動作をインテントモデルと比較します。失敗レポートは、コーディングエージェントが直接対処できるユーザー視点の言葉でプロダクトの動作の乖離を記述します。
その結果、実装から導出されたテストが見逃す失敗を検出するテストスイートが生まれます。内部的には一貫しているが誤っているバグ、コードには一致するがプロダクトには一致しない動作、そしてプロダクトが実際に行うことと構築された目的のギャップです。
今すぐAI IDEにTestSpriteを導入して、プロダクトインテントからのテスト生成を始めましょう。