ずらりと緑のチェックがついたテスト結果を前に、「これ本当に守れているのかな」と一拍おいて画面を見直している開発者

AIが書いた単体テストを信用しすぎない|確認ポイント

「テスト、AIに書いてもらった。全部グリーンだし、もう安心」。 そう思った数日後に、テストは通っているのにバグが出た——という経験、ありませんか。あれはけっこう、こたえます。緑のチェックを信じていただけに、なおさら。

単体テストをAIに頼むと、驚くほど速く、それらしいテストが揃います。しかも、たいてい最初から全部通る。ここに、静かな落とし穴があります。「テストが通ること」と「正しさが守れていること」は、別物だからです。

この記事は、AIに単体テストを書かせること自体を止める話ではありません。むしろ、洗い出しや叩き台づくりは得意分野です。ただ、出てきたテストをそのまま信じてしまう前に、何を確かめているのかを自分の目で見る。そのための確認ポイントを、一緒に整理していきましょう。

結論:AIが書いた単体テストは、①何を検証しているか(仕様か、実装の現状か)→ ②アサーションが意味を持っているか(緩すぎないか)→ ③異常系・境界値が入っているか → ④わざと壊して落ちるか(ミューテーション確認)、の4点を自分の目で見てから信用します。緑であることは出発点であって、ゴールではありません。

テストの本当の役割は、「いま動くこと」を見せることではなく、これから壊れたときに教えてくれることです。そこを守れているかを、落ち着いて見ていきます。

なぜ「全部グリーン」が安心材料にならないのか

すべて緑のテスト結果でも、検証している中身が浅ければ守れる範囲は狭いことを、緑のチェック列とその下の薄いカバー範囲で示した図

AIは、聞かれたことに「それらしく動くもの」を返すのが得意です。テストも同じで、まず通ることを優先したテストを書きがちです。それ自体は悪意ではなく、ただの性質です。ただ、その結果として、こんなことが起きます。

どれも、実行すれば緑になります。だから、結果画面を見ただけでは気づけません。緑は「いまこのテストのとおりに動いた」という事実であって、「正しい」とも「これから守れる」とも言っていないのです。

特にやっかいなのが、最初の「実装の現状をそのまま写す」です。もし元のコードにバグがあれば、AIはそのバグを「正しい挙動」と思い込んでテストに固定します。すると、あとで誰かがバグを直したときに、正しい修正のほうがテストで落ちる——という逆転が起きます。これは、テストがバグを守ってしまっている状態です。

確認の4ステップ(緑になった後にやること)

先に全体像を出します。テストが通ったあと、信用する前に、この順で目を通します。

ステップ見るところひとことで言うと
①何を検証しているか期待値の出どころ「仕様?それとも現状?」
②アサーションの強さ何を確かめているか「中身まで見てる?」
③異常系・境界値ケースの幅「壊れ方も試してる?」
④わざと壊すテストの感度「バグを入れたら落ちる?」

ポイントは、①と④です。①で「仕様を守るテストか、現状をなぞるテストか」を見分け、④で「そもそもこのテストはバグに反応するのか」を確かめます。1つずつ見ていきましょう。

ステップ1:何を検証しているかを見る(仕様か、現状か)

いちばん大事なのは、期待値がどこから来たかです。 テストの「期待する結果」が、仕様(こうあるべき)から来ているのか、実装の現状(いまこう返ってくる)から来ているのか。ここを見分けます。

見分け方は、こう自問することです。

後者だと、コードが間違っていても、テストは「正しい」と言い続けます。AIに頼むと、手元のコードの出力を期待値にしてしまうことがよくあるので、ここは必ず人が見ます。

確かめるときは、AIにこう聞くのも有効です。

このテストの各期待値は、仕様のどの部分から導かれていますか。
仕様ではなく現在の実装の出力をそのまま期待値にしている箇所があれば、
正直に指摘してください。

ただ、現場にはきちんとした仕様書が無い・仕様は口頭だけということも多いはずです。その場合は、「仕様のどこから導いたか」のかわりに、関数名と、既存の正常系コードから読み取れる「本来こうしたいはず」という意図を基準にしてかまいません。期待値がその意図とずれていないかを見るだけでも、現状をなぞっただけのテストはかなり見抜けます。

そのうえで、自分が意図を知っている関数を1つ選び、期待値がその意図と合っているかを確かめます。1つでも「あれ、これ現状をなぞってるだけだ」が見つかれば、他も同じ目で見直す合図です。

ステップ2:アサーションが意味を持っているか

動いたことだけ確認する弱いテストと、戻り値の中身まで確認する強いテストを左右に並べ、見ている深さの差を示した比較図

次に見るのは、そのテストが結局なにを確かめているかです。 よくあるのが、「例外が出ずに最後まで動いた」だけで満足しているテスト。処理が走りきること自体は確認できますが、戻り値が正しいかは何も見ていません。これは緑になりますが、中身が間違っていても気づけません。

見たいのは、こんな点です。

たとえば、合計金額を返す関数なら、「エラーが出ないこと」ではなく「合計がいくらになるか」を確かめないと意味がありません。AIのテストは、ここが緩いことがあります。

緩いアサーションを見つけたら、「この戻り値の、どの項目まで確認すべきか」を自分で決めて、足りなければ足す。テストは、確かめている範囲の分しか守ってくれません。

ステップ3:異常系と境界値が入っているか

正常系がきれいに並んでいても、壊れ方を試していないテストは、本番で壊れたときに無力です。 ここは、テストケースの洗い出しと同じ視点で見ます。

確認したいのは、最低限この4つの観点が入っているかです。

AIに任せると、ここが薄くなりがちです。足りないと感じたら、観点を指定して追加で出させます。

このテストに、次の観点が抜けていないか確認し、足りなければ追加してください。
- 異常系(不正な入力・想定外の状況で、正しく失敗するか)
- 境界値(上限・下限・ちょうど・空・0件)
- 失敗時に、期待どおりのエラーになっているか

観点ごとに足していくと、「動くこと」を見るテストから、「壊れ方も見張る」テストに変わっていきます。なお、テストケースそのものの洗い出し方はAIにテストケースを洗い出させる|観点の与え方に詳しくまとめました。

ステップ4:わざと壊して、落ちることを確かめる

ここが、いちばん効く確認です。 テストが本当にバグに反応するのかは、実際にコードを壊してみれば分かります。これは「ミューテーション(変異)」と呼ばれる考え方の、手でできる簡易版です。

やり方は単純です。

  1. テスト対象のコードを、わざと1か所だけ間違える(例:+- に、>>= に、条件を反転させる、戻り値を少しずらす)。
  2. その状態でテストを走らせる。
  3. テストが赤くなれば合格。そのテストは、ちゃんとバグを見張れています。
  4. 壊したのに緑のままなら危険信号。そのテストは、何も守れていません。
  5. 確認できたら、コードを元に戻す。

「全部グリーン」を見て安心していたテストでも、わざと壊すと緑のままということは、実際よくあります。それは、アサーションが緩いか、肝心の経路を通っていない証拠です。

この手作業は効果が高い一方、毎回やると時間が読めません。そこで、PRごとに必ずやるのではなく、お金・在庫・権限など「壊れたら困るロジック」を触ったときだけ発動する、と決めておくのがおすすめです。それ以外の変更まで毎回やる必要はありません。対象を絞ったうえで、壊れたら困る所を2〜3か所だけ試せば十分、テストの「感度」が見えてきます。AIにこう頼んで、壊しどころを挙げてもらうのも手です。

このコードで、もし1行だけバグを入れるとしたら、影響が大きいのはどこですか。
その変更で、いまのテストが赤くなるかどうかも併せて教えてください。

ただし、ここでもAIの答えを鵜呑みにせず、実際に自分の手で壊して、赤くなるのを目で見て確かめるのが大事です。テストの感度は、机上ではなく実行で確かめます。

ありがちな落とし穴と、その回避

単体テストをAIに任せるとき、つまずきやすい所を先に潰しておきます。

落とし穴のほとんどは、「テストが緑=完了」と捉えた瞬間に生まれます。「緑になってからが確認の始まり」と置き換えるだけで、多くは避けられます。

明日からやること(小さく始める3つ)

いきなり全部やろうとせず、まずこの3つから。

  1. 次にAIのテストを受け取ったら、期待値を1つだけ仕様と照らす:現状をなぞっていないかを確認します。
  2. 「動いた」だけのアサーションを1つ見つけて、戻り値の中身を足す:守備範囲が一段広がります。
  3. 大事な分岐を1か所わざと壊して、赤くなるか見る:テストの感度が分かります。

この3つだけでも、「全部グリーンだけど本当に大丈夫かな」という、あの落ち着かない感じが、少し軽くなります。

コピーして使う「AIテスト確認チェックリスト」

AIが書いた単体テストを受け取ったら、信用する前に上から確認します。全部に○が要るわけではなく、関係する所だけで十分です。重要な関数(金額・在庫・権限・外部連携)を優先し、単純なgetter等は省略可。

① 何を検証しているか

② アサーションの強さ

③ ケースの幅

④ わざと壊す

最後に

テストの正しさを、ひとりで全部背負うのは、しんどいものです。 AIが速く揃えてくれるぶん、「これ、本当に信じていいのか」という確認の負担が、こっそり自分に乗ってきます。その感覚は、たぶん間違っていません。

わざと壊して赤くなることを確かめ、テストの中身に納得して、安心して次の作業へ進もうとしている開発者

でも、緑を鵜呑みにせず、「これは何を守ってくれているのか」を一度のぞくだけで、テストは「速くて頼りないもの」から「速くて信頼できるもの」に近づきます。 全部でなくて大丈夫です。今日ひとつ、大事な分岐をわざと壊して赤くなるのを見られたなら、それはもう、テストを信じられる足場ができはじめた証拠です。AIに書かせたコードそのものを見る型はAI生成コードのレビュー・検証チェックリストに、動かして確かめる型は生成コードをそのまま使わない|最低限の動作確認の型に。書かせる・確かめる・見張る。この3つがそろうと、AIとのテストはずいぶん落ち着きます。

関連用語