AIが生成したバグ修正が実際に機能しているかを確認する方法

AIコーディングエージェントがバグの修正を提案し、コードが変更され、元のエラーが表示されなくなります。これはしばしば修正が成功した証拠として扱われます。しかし実際には、報告された特定の症状が、確認された特定の方法で表示されなくなったという、より限定的な確認にすぎません。「バグが修正された」という主張より範囲が狭いのです。
「エラーが消えた」は「修正された」とは違う
バグ修正は、報告された症状を解決しながら、根本的な問題を部分的に残したり、修正された問題の隣に新たな問題を引き起こしたりすることがあります。どちらのパターンもAIが生成した修正では十分起こり得るため、「エラーが消えた」ことを確認するだけでは不十分です。
最初のパターンは、エージェントがバグレポートの直接的なトリガーに対処しながら、それを引き起こした根本的な状況には対処しない場合に発生します。特定の画面でのnullポインターエラーが、その特定のクラッシュを防ぐチェックでパッチされます。一方、そもそもnull値を引き起こしたデータの不整合はそのまま残り、別の場所で表面化する可能性があります。
2番目のパターンは、修正自体がコード変更であり、コード変更には副作用が生じる可能性があるために起こります。あるバグの修正が、元のバグレポートとは無関係な隣接機能にリグレッションをもたらすことがあります。
修正を実際に確認するために必要なこと
修正が機能したことを確認するには、1つではなく3つの別々の事項を確認する必要があります。
報告された元の動作が正しく機能するようになっていること。これは当然のチェックであり、必要ではありますが、それだけでは十分ではありません。
バグの周辺状況も解消されていること(特定のトリガーだけでなく)。バグが「レポートの行数がゼロの場合にエクスポートボタンがクラッシュする」であれば、バグが最初に発見されたときたまたま開いていたレポートでボタンがクラッシュしなくなったことを確認するだけでなく、具体的にゼロ行のケースをカバーする必要があります。
修正の隣接部分で副作用として何も壊れていないこと。これには修正の直接領域を超えたテストが必要で、変更されたものとコード・データ・状態を共有するフローをカバーする必要があります。
なぜ単純な再実行ではなくプロダクトレイヤーの検証が必要なのか
元のバグレポートの正確な手順を再実行して修正を確認することは、上記の3つの事項のうち最初の1つしかチェックしません。これは、パッチが当てられた穴が、最初に漏れが確認された角度から漏れていないことを確認しながら、異なる条件下でパッチが保つかどうか、あるいは周囲の部分に影響を与えていないかを確認しないのと同じです。
TestSpriteはプロダクトレイヤーで検証を行い、実行中のアプリケーションを開いて、元のレポートの1つの条件だけでなく、複数の条件下で修正された領域をテストします。
他の検証ツールはコードを読んで推測します。TestSpriteはあなたのアプリを開いて実際に使います。
MCPサーバーを通じて接続し、元のバグを発見するために使用した同じトリガー指示「TestSpriteでこのプロジェクトをテストして」を修正の確認にも使用できます。探索エージェントはそのフローを再訪し、報告されたケースと隣接するバリエーションを試し、副作用がないか周辺機能を確認します。
シナリオ:コワーキングスペース予約アプリと別の問題を引き起こした修正
コワーキングスペース向け予約アプリを開発しているチームがバグレポートを受け取ります。デイパス会員が、フル会員のみに制限されているはずの会議室予約オプションを閲覧できるというものです。
Claude Codeに修正を依頼します。エージェントは会議室の表示を制御するパーミッションチェックを特定し、デイパス会員が制限されたオプションを表示できないよう修正します。開発者は元のシナリオを手動で再実行し、デイパスアカウントで会議室予約オプションが非表示になったことを確認して、修正が完了したと判断します。
マージする前に、開発者は手動のスポットチェックに頼らずTestSpriteをトリガーします。探索エージェントは、元のレポートのアカウントだけでなく、デイパス会員・フル会員・管理者アカウントの複数のアカウントタイプで修正をテストします。デイパス会員では修正が正しく機能しています。しかし管理者アカウントでは、同じパーミッションチェックが会議室オプションも非表示にしており、これは誤った動作です。修正は会員ティアに対するチェックとして実装されましたが、管理者アカウントには標準の会員ティア値がないため、ロジックが誤って管理者ロールを許可リストから完全に除外していました。
これは修正自体が引き起こした実際のリグレッションであり、元のバグレポートでは一切言及されず、手動確認でも決してチェックされなかったアカウントタイプで発生しています。失敗の説明には、どのアカウントタイプのどのパーミッションが誤って動作したかが正確に記載されています。コーディングエージェントは管理者ロールを明示的に含めるようチェックを調整し、TestSpriteはデイパスが制限・フル会員が許可・管理者が許可という3つのアカウントタイプすべてが正しく動作することを確認します。
修正検証を元のテストと同じループに組み込む
これを特別な追加作業ではなく習慣にするための最も確実な方法は、修正検証を元のテストと同じアクションとして扱い、別の手動プロセスとしてではなく、変更後に同じトリガー文を再実行することです。バグを発見した同じトリガー文を修正の確認にも使用します。
同じセッションではなくプルリクエストに入る修正の場合、GitHub Actionsインテグレーションが同じカバレッジを自動的に提供します。修正を含むPRがプレビューデプロイメントに対してテストをトリガーし、修正と周辺機能をマージ前に確認して、結果がdiffと並んでレビュアーが見るコメントとして投稿されます。
まとめ
元のエラーを消した修正は、最低限のハードルをクリアしたにすぎず、検証全体を終えたわけではありません。実際に機能していることを確認するには、元のトリガー周辺の広い状況をチェックし、修正が隣接する箇所に副作用をもたらしていないかを確認する必要があります。
TestSpriteはバグを発見するのと同じ方法で修正を検証します。元のレポートの1つのシナリオを再実行するのではなく、実際の条件下で実行中のアプリケーションを開いて修正された領域をテストします。
TestSpriteを使って修正を確認し、「エラーが消えた」をバグが実際に解消された証拠として扱うのをやめましょう。