
境界値・異常系をAIに考えさせて漏れを減らす手順
「テストも書いといて」とAIに頼んだら、それらしいテストがずらっと返ってきた。 一見よくできている。でも中身を見ると、入力が正しくて、結果も正しいケースばかり。空文字を入れたら、上限を超えたら、通信が落ちたら——そういう「うまくいかない側」のテストが、ほとんど無い。
この「正常系はあるのに、端っこと異常系が抜けている」という状態は、AIにテストを書かせると、かなりの確率で起こります。あなたの頼み方が悪いわけではありません。AIは「動く例」を作るのは得意でも、「壊れる条件」を自分から網羅しにはいかないからです。だからこそ、境界と異常系は、こちらから観点を渡して考えさせる。この記事では、その渡し方と、返ってきたテストの抜けを確認する手順を、コピーして使える形で整理します。
結論:AI生成テストの穴は、ほぼ決まって「境界値」と「異常系」に空きます。埋め方は3ステップ。①正常系はAIに任せ、境界・異常系はこちらから観点を渡す(下限・上限・その±1・空・ゼロ・最大長・null/不正な型・権限なし・タイムアウトなど)。②渡すときは「この関数の入力ごとに、正常・境界・異常の3列でテスト観点を先に洗い出して」と、コードより先に観点表を作らせる。③返ってきたら、入力の各項目に境界と異常が1つずつ以上あるかだけ数える。抜けていたら、その項目名を挙げて「この観点が無い、足して」と返す。テストを増やすより、観点の抜けを1項目ずつ埋めるほうが速くて確実です。
正常系ばかりになるのは、AIがサボっているからではありません。 学習データにあるテストの多くが「こう使えば動く」を示す例で、意図的に壊す例は相対的に少ない。だからデフォルトでは「動く証明」に寄ります。壊れる条件を探すのは、指示があって初めて本気を出す領域だと思っておくと、付き合い方が楽になります。今日は、その本気を引き出す渡し方を、一緒に見ていきましょう。
なぜAIのテストは正常系に偏るのか

AIにテストを頼むと正常系に寄るのは、大きく3つの理由があります。
まず、「テスト」という言葉だけでは、どこまで壊すかが伝わらないこと。人間なら「テスト書いて」と言われれば経験的に異常系まで想像しますが、AIは指示された範囲を素直に埋めます。範囲を絞らなければ「動く例をいくつか」で止まりがちです。
次に、異常系は仕様を知らないと書けないこと。「上限は100」「空はエラーにする」といったルールは、コードやあなたの頭の中にあって、AIの手元には無いことが多い。境界がどこかを知らなければ、境界値テストは作れません。
そして、壊れる条件は無限にあるように見えること。あらゆる異常を挙げようとすると発散するので、AIは無難な正常系に落ち着きます。ここは人間側が「この関数で気にすべき異常はこれとこれ」と枠を与えると、途端に具体的になります。
だから対策はシンプルです。正常系はお任せ、境界と異常系はこちらが観点を渡す。次の章で、その観点の中身を見ていきます。
まず押さえる「境界値」と「異常系」の定番観点
境界と異常は、実は毎回だいたい同じ所に出ます。関数を見ながら、次のリストを上から当てていくだけで、かなりの抜けが埋まります。
境界値(正常と異常の境目)
- 下限ちょうど/下限の1つ下/下限の1つ上
- 上限ちょうど/上限の1つ上/上限の1つ下
- ゼロ/マイナス(数値の場合)
- 空(空文字・空配列・空リスト)/要素1つ/最大件数
- 文字数の下限・上限(0文字・1文字・最大長・最大長+1)
異常系(そもそも想定外の入力・状態)
- null/未定義/型が違う(数値のはずが文字列 など)
- フォーマット違反(日付でない文字列、不正なメールアドレス など)
- 権限がない/ログインしていない状態での呼び出し
- 依存先が失敗する(DB・外部APIのエラー、タイムアウト、通信断)
- 同時に呼ばれる/重複して呼ばれる(二重送信 など)
このリストは、覚えるというより手元に置いて毎回なぞるものです。 すべてが全部の関数に当てはまるわけではありません。「この関数に関係あるのはどれか」を選ぶだけでいい。関係する行にチェックを入れ、それをAIへの指示に使います。ゼロから異常を発想するより、定番リストから選ぶほうが、速くて漏れにくいからです。
特に見落とされやすいのが、下限・上限の「±1」と、依存先の失敗の2つ。ちょうどの値は書けても、その1つ外側が抜ける。正常に動くAPIは想定しても、落ちたAPIを想定し忘れる。この2つを毎回思い出すだけでも、本番の「まさか」がかなり減ります。
手順①:コードより先に「観点表」を作らせる
いきなり「境界値テストも書いて」と頼むと、AIは思いついた分だけ書いて、やはり抜けます。 おすすめは、テストコードを書かせる前に、テスト観点の表だけ先に出させること。表の形にすると、抜けが目で見えます。
聞き方の例:
次の関数のテスト観点を、コードはまだ書かずに表で洗い出してください。
入力・状態の項目ごとに、次の3列で挙げてください。
| 対象(入力/状態) | 正常系 | 境界値 | 異常系 |
境界値は下限・上限とその±1、空・ゼロ・最大長を意識してください。
異常系は null・型違い・権限なし・依存先(DB/外部API)の失敗・タイムアウトを
関係するものだけ挙げてください。
表が埋まってから、こちらがOKを出したらテストコードにします。
こう頼むと、返ってくるのは表です。 ここで大事なのは、表の段階なら抜けを直すのが一瞬だということ。「上限の欄が空いてる」「タイムアウトが無い」と、埋まっていないセルを指さすだけで済みます。コードまで書かせてから直すより、はるかに軽い。
表を見て、前章の定番リストと照らします。関係する観点なのにセルが空なら、「この対象の異常系にタイムアウトを足して」と一言。表が納得いく形になってから、はじめて「この表どおりにテストコードを書いて」と進めます。設計図(観点表)を先に合意してから、施工(コード)に入るイメージです。
手順②:返ってきたテストの抜けを「数えて」確認する
コードが返ってきたら、読み込む前に、まず数える確認をします。感覚で「足りてなさそう」と思うより、機械的に数えるほうが速くて確実です。
見るのは1点だけ——入力・状態の各項目に、境界と異常が1つ以上あるか。
- 入力Aについて:正常のテストがある? 境界のテストがある? 異常のテストがある?
- 入力Bについて:同上
- 依存先(DB・API)について:失敗したときのテストがある?
各項目で「境界ゼロ個」「異常ゼロ個」の所が、埋めるべき穴です。 たとえば「金額」という入力に、正しい金額のテストは3つあるのに、0円・マイナス・上限超えが1つも無ければ、そこが抜け。「外部API呼び出し」があるのに、APIが失敗したときのテストが無ければ、そこも抜け。
穴が見つかったら、その項目名を挙げて、狙い撃ちで足させる。
金額の境界値が抜けています。0円・マイナス・上限ちょうど・上限+1のテストを足してください。
外部API呼び出しについて、失敗時(エラー応答・タイムアウト)のテストも足してください。
「全部見直して」ではなく「この項目のこの観点が無い」と具体的に返すのがコツです。 そうすると、AIは既にあるテストを壊さずに、足りない分だけ追加します。抜けを1項目ずつ潰していく感覚で、表と突き合わせながら埋めていけば、正常系だらけだったテストが、境界と異常まで届く形に育ちます。
手順③:AIが作った異常系テストを鵜呑みにしない
境界・異常のテストが増えたら安心——と行きたい所ですが、もう一段だけ確認があります。 AI が書いた「異常系のはずのテスト」が、本当に異常系を検証できているかです。ここは人が見る所です。
よくある落とし穴は3つ。
- 期待値がAI任せで、仕様と食い違う:「不正な入力ならエラー」とテストしていても、あなたの仕様では「エラーにせず0を返す」かもしれない。期待している結果が仕様どおりかは、AIではなくあなたが決めます。
- 例外を投げる想定なのに、投げなくても通ってしまう:異常系テストの書き方が甘いと、実際にはエラーになっていないのにテストが緑になることがあります。「わざと壊して、ちゃんと落ちるか」を一度確かめると安心です。
- 境界の値が、仕様の境界とズレている:AIが「上限は100だろう」と推測で書いていることがあります。本当の上限が1000なら、そのテストは意味を持ちません。境界の数字は仕様で裏を取る。
これらは、テストの本数では測れません。 だから最後は、代表的な異常系テストを2〜3個だけ、自分で仕様と突き合わせる。全部でなくていい。「一番大事な異常系(お金・権限・データ消失に関わる所)」だけは、期待値が仕様どおりか自分の目で確認する。ここを人が担保すれば、AIに数を任せても足元が崩れません。テストを信用しすぎない構え全般は生成された単体テストを信用しすぎないための確認ポイントにも整理しています。
ありがちな落とし穴と、その回避
境界・異常系をAIに任せるとき、つまずきやすい所を先に潰しておきます。
- 「テスト書いて」だけで頼む:正常系に偏る。境界・異常の観点を渡し、先に観点表を作らせる。
- 異常を全部発想しようとして発散する:定番リスト(下限上限±1・空・null・型違い・権限・依存先失敗・タイムアウト)から関係するものを選ぶ。
- 上限・下限の「ちょうど」だけ書いて±1を忘れる:境目の1つ外側こそバグが出やすい。±1をセットで。
- 依存先が成功する前提しか作らない:DB・外部APIは落ちる前提のテストを1つは持つ。
- AIの期待値をそのまま信じる:異常系の期待結果が仕様どおりかは人が決める。特にお金・権限は自分で確認。
- 境界の数字をAIの推測に任せる:上限・下限の値は仕様で裏を取る。推測のままだと空振りする。
落とし穴の多くは、「AIが出したテストの本数」で安心してしまう所から生まれます。 本数ではなく、各入力に境界と異常が1つずつあるか。この見方に切り替えるだけで、抜けにずっと気づきやすくなります。
明日からやること(小さく始める3つ)
いきなり全テストを見直さなくて大丈夫です。まずこの3つから。
- 次にAIへテストを頼むとき、「コードの前に観点表を作って」と一文足す:正常・境界・異常の3列で洗わせると、抜けが目で見えます。
- 返ってきたテストを、入力ごとに「境界ある? 異常ある?」で数える:ゼロの所だけ、項目名を挙げて足させます。
- 一番大事な異常系(お金・権限・データ)のテストだけ、期待値を仕様と突き合わせる:全部でなく、崩れると痛い所だけ人が確認します。
この3つだけでも、「正常系ばかりで不安」というテストが、少し頼れるものに変わります。
コピーして使う「境界・異常系の観点渡しシート」
AIにテストを頼む前後で、上から順に使ってください。一度に全部でなく、気になる関数だけでも十分です。
# 境界・異常系テストの観点渡し
## 頼む前:この関数で気にする観点を選ぶ(関係するものに✓)
境界値:
- [ ] 下限ちょうど / 下限±1
- [ ] 上限ちょうど / 上限±1
- [ ] 空(空文字・空配列) / 要素1つ / 最大件数
- [ ] ゼロ / マイナス
異常系:
- [ ] null・未定義・型違い
- [ ] フォーマット違反(日付・メール等)
- [ ] 権限なし・未ログイン
- [ ] 依存先の失敗(DB・外部API・通信断)
- [ ] タイムアウト / 二重呼び出し
## 頼み方:コードより先に観点表を作らせる
「コードはまだ。入力/状態ごとに 正常・境界・異常 の3列で観点表を出して」
## 返ってきたら:入力ごとに数える
- 入力1:境界ある? 異常ある?(無ければ項目名を挙げて足させる)
- 入力2:同上
- 依存先:失敗時のテストある?
## 最後に人が見る(全部でなく大事な所だけ)
- [ ] 一番痛い異常系(お金・権限・データ)の期待値が仕様どおりか
- [ ] 境界の数字(上限・下限)が仕様と一致しているか
- [ ] わざと壊したとき、テストがちゃんと落ちるか
境界・異常系の前後チェックリスト
テストを頼むときと、受け取ったときに、さっと確認します。全部に○が要るわけではなく、関係する所だけで十分です。
頼むとき
- 正常系はお任せ、境界・異常系は観点を渡す形にしたか
- コードより先に「観点表」を作らせたか
- 定番リストから、この関数に関係する観点を選んだか
- 上限・下限の「±1」と「依存先の失敗」を入れたか
受け取ったとき
- 入力・状態の各項目に、境界と異常が1つ以上あるか数えたか
- 抜けは「項目名+観点」を挙げて狙い撃ちで足させたか
- 大事な異常系の期待値を、自分で仕様と突き合わせたか
- 境界の数字を仕様で裏取りしたか(AIの推測のままにしていないか)
最後に
AIが返したテストが正常系ばかりで、「これで本当に大丈夫だろうか」と不安になる。 その感覚は、むしろ正しいです。抜けに気づけている時点で、あなたはもう品質を守る側に立っています。テストが正常系に寄るのは、あなたの頼み方の問題ではなく、AIの出し方の特性です。

一度に完璧な網羅を目指さなくて大丈夫です。今日ひとつ、「観点表を先に作らせる」だけ試してみる。それだけで、AIのテストが、端っこと異常系まで届く形に一歩近づきます。 テストを信用しすぎない構えは生成された単体テストを信用しすぎないための確認ポイントに、観点の与え方全般はAIにテストケースを洗い出させるときの観点の与え方に整理しています。壊れる条件を、こちらから渡す。その一手さえ持てば、AIに数を任せても、足元が崩れることはありません。