AIで自動テスト生成はすべて詐欺です
今日, AIエージェントを使ったコード生成はかなり一般的になってきました. それにともなって, AIを使って自動テストを生成するといった事例も増えてきました.
AIを使った自動テスト生成の対象となるテストはいわゆる開発者テストと呼ばれるプロダクトコードと対応するテストのはずです. 2025年8月現在, これらのテストをAIを使って手放しに生成できません.
この記事ではAIによる自動テスト生成の問題点を挙げ, AIを使ったテスト設計の可能性について考察します.
AIによる自動テスト生成の問題点
AIによる自動テスト生成が失敗するのは以下のような点が考慮されていないからです.
- テストは設計の一部であること
- テストはエンジニアリングの根幹であること
まずはこれらの問題点を深掘りしていきます.
テストは設計の一部
開発者テストはプロダクトコードの検証を担うだけでなく, プロダクトコードがどのようにふるまうべきかを示す設計の役割を担っています. テストをAIに丸投げすることは, プロダクトコードの設計判断をAIに委ねることと同義です. 要件を満たすだけの素朴な実装はできるでしょうが, 長期的なエンジニアリングを意識した設計は難しいでしょう.
テストには以下を説明し検証する役割を持ちます.
- テスト対象システムはどのような契約(事前条件・事後条件)を持つか
- 将来の変更に対してどのような影響があるか
これらはプロダクトコードが要件に対して多様な観点とトレードオフを持つことを示しています. AIだけではこれらを解決できず, ヒトが判断しなければなりません.
テストはエンジニアリングの根幹
テストはプロダクトコードを評価するだけではありません. 自動テストはエンジニアリングプロセスのあらゆる時点で実行されます. CI/CDには必ず自動テストが組み込まれて何度も実行されます. リファクタリングには動作を保証するための自動テストが必要です. このように現代の開発プロセスにおいて自動テストは欠かせない要素となっています.
しかし現実にはそううまくいきません. 自動テストには以下のような多くの問題があります[1][2].
- 偽陽性・偽陰性
- flaky test
- 脆いテスト
- スローテスト
効果的なテストを書くためには, これらを考慮しコントロールする必要があります. ソフトウェアエンジニアリングにおいて非常に困難な課題であり, 今現在AIを使えば簡単に解決できるものではありません.
こういった問題があるため, 今のところAIを使って手放しで自動テストを生成できないのです.
AIを使ったふるまい駆動開発(BDD)
AIを活用するうえで重要なのが, きちんと設計をやり抜くことです. 設計を重視したAIエージェントツールとして Kiro が出てきましたが[3], それよりももっとプリミティブな方法があります. それがふるまい駆動開発(BDD) です[4].
Gherkin 記法による要件定義とテスト設計
BDDでは Gherkin 記法を用いて feature ファイルにテストシナリオを自然言語で記述します. 自然言語でありながら構文を用いてテストを定義できるため, 要件に対する実装の定義と検証に集中できます. またこういった記述形式はAIエージェントにとっても扱いやすいものです. こここそがAIエージェントを活用するポイントです.
Feature: Guess the word
# The first example has two steps
Scenario: Maker starts a game
When the Maker starts a game
Then the Maker waits for a Breaker to join
# The second example has three steps
Scenario: Breaker joins a game
Given the Maker has started a game with the word "silky"
When the Breaker joins the Maker's game
Then the Breaker must guess a word with 5 characters
テスト容易性を考慮したインターフェース設計
BDDによりユーザー視点での機能分割が可能になります. これにより機能別のモジュール設計となります. ただし内部実装はこれより細かい単位で行います. そこでモジュール内部ではテスト容易性を考慮して関数単位で設計します[5]. いわゆるテスト駆動開発 (TDD: Test-Driven Development) です.
テスト容易性のために考えることは Test sizes とテスト手法です[6][7].
Test sizes
Test sizes はテストが必要とするリソースによって分類したものです.
- Small test: 実行プロセスは単一.
- Medium test: 単一のマシン. 複数プロセス.
- Large test: 複数のマシン. 複数プロセス.
テスト手法
『単体テストの考え方/使い方』で紹介されているテスト手法の分類はテストの検証方法によって分類します.
- 出力値ベース・テスト: 戻り値を確認するテスト
- 状態ベース・テスト: 状態を確認するテスト
- コミュニケーションベース・テスト: オブジェクト間のやり取りを確認するテスト
目指すべきは small test かつ出力値ベース・テストです. まずはこの形式になる重要なドメインロジックを見つけます. この形式のテストでカバーできる領域を増やすことが設計の肝です. 次に状態ベース・テストとして表現できるロジックを見つけます. test size も medium test となる可能性があり, またクラス設計なども必要になり複雑になってきます. 意味のあるテストかどうかをきちんと考える必要があります. 状態だと思っていたものも, 継続[8]などを使うことで出力値ベース・テストにできる場合があります. 最後にコミュニケーションベース・テストです. APIを利用しているためコミュニケーションベース・テストとせざるを得ない場合のように, このテストは本質的に外部性が強くなります. テストが必要なロジックは存在するか、継続的にテストを実行していく中で外部性は保証されるかを考えたうえで設計します.
テストダブルの使い方とテスト手法
これらを考慮してテストとインターフェースを設計します. 上のような内容をプロンプトに加えることでAIを使って設計できるかもしれませんが, エンジニアに残された腕の見せ所だと思います(そうだよな? そうだと言ってくれ![11]).
AIによる実装
さてここまでくればあとはほとんどAIに任せられます. この手法はテスト設計とインターフェース設計をまとめてやってからAIに実装させるというよりも, あくまでTDDとしてこれらを考えながら実装をAIと一緒に進めていくやり方です.
BDDによる検証
初めに用意した feature ファイルの内容がここでようやく検証できるようになります. BDDによるテストは受入テストとなるため, 上のようなテストとは別のレイヤーで実装し, 実行します.
自動テストは現代におけるエンジニアリングにおいて重要な役割を担っています. 自動テストの設計はエンジニアリングプロセスそのものを決定づけます. エンジニアリングの領域においては今のところAIエージェントだけでは解決できない課題が多く残っています. こういった問題点を認識し, AIエージェントをうまく活用することが今我々に求められています.
-
クラス単位と読み替えてもかまいません. ユーザーから見える機能より細かい単位という意味です. ↩︎
-
単体テストの考え方/使い方 プロジェクトの持続可能な成長を実現するための戦略, Vladimir Khorikov, 須田 智之, マイナビ出版, 2022 http://book.mynavi.jp/ec/products/detail/id=134252 ↩︎
-
認証や決済などサービスによってはモック・スタブの利用が避けられない場合もありますが, それであってもフェイクを作成するなどして可能な限り避けるべきだと考えています. ↩︎
Discussion