現在の実装ではなく、プロダクトの意図からテストを生成するにはどうすればよいか?

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