テスト生成におけるAI:その有用性と落とし穴

AIはテストを高速に生成します。しかし、一見本物のように見えて、実際には間違った内容を検証しているテストも作成します。

AIにコードを貼り付けると、わずか30秒後には12個のテストがパスしています。カバレッジスコアは上がり、生産性が向上したように感じられるでしょう。

しかし、その後本番環境でバグが発生します。その12個のテストを見返してみると、どれ一つとしてそのバグを検知できなかったことに気づくのです。

AIがテストしたのは「コードが実際に何をしているか」であり、「コードが本来何をすべきか」ではありませんでした。

AIは有用ですが、その正しい使い道を知っておく必要があります。

AIが得意なこと:

  • setupやteardownブロックのようなボイラープレートの生成。
  • 繰り返しの多いfactoryヘルパーやデータオブジェクトの記述。
  • 優れたテストパターンのバリエーションを多数作成すること。
  • null、空文字、ゼロといった明白なエッジケースの処理。

AIが苦手なこと(失敗する場面):

  • 実装に依存したテスト: ビジネスロジックではなく、コードの構造に従ったテストを書いてしまいます。そのため、結果が正しくてもコードをリファクタリングするだけでテストが壊れてしまいます。
  • 浅いエッジケース: 明らかなエラーは見つけますが、ドメイン固有のバグは見逃します。タイムゾーンの癖やデータベースの制約、特定のビジネスルールなどは理解していません。
  • 脆いモック: 本来実物であるべき内部サービスをモック化してしまいます。これにより、テストのメンテナンスが困難になり、リファクタリング時に壊れやすくなります。

「テスト演劇(Test Theater)」に陥らずにAIを活用する方法:

  1. まず「契約(Contract)」を定義する: テストが何を証明すべきかを、平易な言葉で一文で書きます。例:「期限切れのコードは、元の金額を返さなければならない」。
  2. その一文をAIに渡す: コードの記述はAIに任せますが、「意図」は人間が責任を持つ必要があります。
  3. モック化は境界部分のみに留める: 内部モジュールには実体を使用します。外部APIやデータベースのみをモック化してください。
  4. ドメイン固有のエッジケースを一つ、手動で書く: AIは「明白な」エッジケースを処理しますが、実際に本番環境のインシデントを引き起こすような「深夜3時の(極めて厄介な)」エッジケースは、人間が対処しなければなりません。

テストが何を検証するかをAIに決めさせてはいけません。AIはコードを記述するために使い、ロジックは人間が提供するのです。

Source: https://dev.to/nazar_boyko/ai-for-test-generation-where-it-helps-and-where-it-lies-jhm