
AIにテストの命名・意図コメントを整えさせる|落ちた時に読めるテスト
夜、CIが赤くなった。 通知を開くと、落ちたテストの名前は test calculate 2。もう1つは 正しく動くこと。何が壊れたのか、名前からはまったく読めない。結局テストの中身を上から読み、期待値の 4999 が何の数字なのかを探すところから始まる——そんな経験、ありませんか。
AIにテストを書かせるようになってから、こういう場面が増えたと感じている人は多いと思います。あなたのレビューが甘かったわけではありません。AIは「このテストが落ちたとき、誰が何を知りたいか」を知らないまま名前をつけているので、ここは人が少しだけ手を貸す所なんです。この記事では、落ちた時に読めるテストへ、AIと一緒に整える手順をまとめます。
結論:AIが書いたテストは、①テスト名を「条件・操作・期待」の3つで言えているかを見て、②意図コメントは「なぜこの値・このケースなのか」だけに絞り、③AIには「アサーションも処理も変えず、名前とコメントだけ」と範囲を区切って候補を出させる、の3手順で整えます。中身から意図が読み取れないテストは、AIにそれらしい理由を作らせず「要確認」で止める。意図を知っているのは人、言葉を整えるのはAI、という分担がちょうどいい距離です。
テスト名は、テストが落ちたその瞬間に、いちばん最初に読まれる文章です。 全部を書き直す必要はありません。よく落ちるテスト、大事な仕様を守っているテストから数本整えれば十分です。
なぜAIのテストは「落ちても読めない」になりやすいのか
AIのテスト名がぼんやりするのは、AIが手を抜いているからではなく、名前を決める材料が足りないからです。よく見かけるのは次の3つです。
- 関数名をなぞった名前:
test_calculate、calculateShipping works。何の関数を呼んでいるかは分かりますが、どんな条件で、どうなるべきかが抜けています。同じ関数のテストが5本並ぶと、test_calculate_2、_3……と番号で区別するしかなくなります。 - 「正しく動く」系の名前:
should work correctly、正常に処理されること。何をもって「正しい」とするかが名前にないので、落ちても「正しくなかった」としか分かりません。 - コードを言い直すだけのコメント:
// 5000を渡す、// 結果が0であることを確認。コードを読めば分かることを日本語にしただけで、なぜ5000なのかは書かれていません。
どれも、AIが仕様の背景(なぜその境目なのか、誰が困るのか)を知らないことから起きています。逆に言えば、そこを人が少し渡すだけで、ぐっと読めるテストになります。
テスト名は「条件・操作・期待」の3つで言う

読めるテスト名には、だいたい3つの要素が入っています。
- 条件:どんな状態・どんな入力のとき(例:合計が5,000円ちょうどのとき)
- 操作:何をしたら(例:送料を計算すると)
- 期待:どうなるべきか(例:送料は0円になる)
この3つが名前に入っていると、テストが落ちた瞬間に「合計5,000円ちょうどで送料無料にならなくなった」と、中身を開く前に分かります。書き方の流儀(describe で条件をまとめる、given_when_then 形式にする、日本語で書く等)はチームによって違って大丈夫です。大事なのは形式より、3つが読み取れるかどうかです。
たとえば、AIがこんなテストを書いたとします(送料は「合計5,000円以上で無料、未満は500円」という仕様)。
describe('calculateShipping', () => {
it('should work correctly', () => {
// 4999を渡す
expect(calculateShipping(4999)).toBe(500);
});
it('test 2', () => {
// 5000を渡す
expect(calculateShipping(5000)).toBe(0);
});
});
中身は大事な境目を確かめている、いいテストです。でも名前とコメントからは、それが伝わりません。整えると、こうなります。
describe('calculateShipping:合計5,000円以上で送料無料', () => {
// 境目の両側を確かめる。仕様の「以上」を「より大きい」と取り違えると、
// ちょうど5,000円の注文に送料がかかってしまうため(チケット #123)
it('合計が4,999円のときは、送料500円がかかる', () => {
expect(calculateShipping(4999)).toBe(500);
});
it('合計がちょうど5,000円のときは、送料が0円になる', () => {
expect(calculateShipping(5000)).toBe(0);
});
});
アサーション(expect(...).toBe(...) の部分)は1文字も変えていません。変えたのは名前とコメントだけです。それでも、落ちたときに読む人の手間はまったく違います。
境目のテストそのものの考え方は、境界値・異常系をAIに考えさせて漏れを減らす手順でも詳しく書いています。
意図コメントは「なぜ」だけを書く
テストのコメントは、多ければいいわけではありません。残す価値があるのは、コードを読んでも分からないことだけです。
| 書く価値がある | なくていい |
|---|---|
| なぜこの値なのか(境目・過去の不具合の再現値) | 「4999を渡す」などコードの言い直し |
| なぜこのケースが大事なのか(誰が困るか) | 「結果を確認する」などの決まり文句 |
| 仕様やチケットの番号・出どころ | AIが推測でつけた、根拠の分からない理由 |
| わざと変な値を使っている理由 | テスト名と同じことの繰り返し |
とくに気をつけたいのが、表の右下です。AIにコメントを書かせると、理由が分からないテストにも、もっともらしい理由をつけてくることがあります。「4999 は消費税計算の端数を確かめるため」のように、自信ありげに。それが外れていると、ぼんやりしていたテストが間違った意図のはっきりしたテストに変わってしまい、次に読んだ人を迷わせます。
理由が分からないときは、AIにも自分にも「分からない」と書かせるほうが安全です。
AIに整えさせる頼み方(コピーして使えます)
AIに任せるときのポイントは、直す範囲を名前とコメントに区切ることです。「テストを読みやすくして」とだけ頼むと、ついでにアサーションをまとめたり、期待値を実装に合わせて書き換えたりすることがあります。それではテストが守っていたものが変わってしまいます。
まずは、変える前に一覧を出してもらいます。
下のテストコードの「テスト名」と「コメント」だけを見直したいです。
まだコードは書き換えないでください。
各テストについて、次の表を作ってください。
| 今のテスト名 | 実際に確かめていること(条件・操作・期待) | 名前の案 | 名前と中身がずれている点 |
ルール:
- アサーション、入力値、期待値、処理の順番は変えない前提で考える
- 名前の案は「条件・操作・期待」が読み取れる形にする(日本語で)
- 「なぜこの値なのか」がコードや下の仕様メモから読み取れないものは、
推測で理由を書かず「要確認」とし、何を確かめれば分かるかを書く
- テスト名と中身が食い違っている(名前は「マイナスを弾く」なのに、マイナスを渡していない等)ものは、別に一覧にする
--- 仕様メモ(分かる範囲で1〜3行) ---
送料:合計5,000円以上で無料、未満は500円
--- テストコード ---
(貼る)
表が出てきたら、人が見るのは2か所です。
- 「実際に確かめていること」が合っているか:AIの読み取りが外れていたら、名前の案も全部外れます。ここだけはテストの中身と照らして確かめます。
- 「要確認」と「ずれている点」:ここがいちばん価値のある出力です。名前と中身が食い違っているテストは、名前を直すべきなのか、テストの中身が仕様からずれているのかを、人が判断します。
表を確かめたら、書き換えを頼みます。
さきほどの表で、私が確認した名前の案で書き換えてください。
- 変えるのはテスト名とコメントだけ。アサーション・入力値・期待値・処理の順番は一切変えない
- 「要確認」のテストは名前を変えず、コメントに「TODO: 意図要確認(理由:〜)」とだけ残す
- 変更後、変えた行だけが分かる差分で見せてください
出てきた差分は、名前とコメント以外の行が1行も変わっていないことを目で確かめます。AIの変更が範囲を越えていないかの見方は、AIリファクタリングの差分レビュー|壊さず確認する手順の考え方がそのまま使えます。
名前を変える前に、ここだけ気をつける
テスト名の変更は動作に影響しない……ことが多いのですが、いくつか例外があります。
- スナップショットテスト:Jest や Vitest のスナップショットは、テスト名をキーにして保存されています。名前を変えると古いスナップショットが「使われていないもの」として残ったり、新しく作り直しになったりします。更新するときは、中身が同じであることを差分で確かめてからにします。
- 名前で絞り込んで実行している所:CIの設定やスクリプトで、
-t(Jest)や-k(pytest)のようにテスト名の一部を指定して実行していることがあります。名前を変えると、そこで拾われなくなることがあります。リポジトリ内を検索しておくと安心です。 - テストとして認識される名前の決まり:pytest の
test_で始まる関数名のように、フレームワークがテストを見つけるための決まりがある場合、そこは崩さないようにします。 - 名前を変えたら、件数を見る:変更の前後でテストの実行件数が同じかを見ておくと、「いつの間にか1本走っていない」に気づけます。
整えると、何が変わるか
- 夜の赤が怖くなくなる:落ちたテスト名を読めば、どの仕様が壊れたかの見当がつきます。中身を読み解く時間が、直す時間に変わります。
- レビューが仕様の確認になる:テスト名の一覧が、そのまま「このコードが守っていること」の一覧として読めます。抜けている条件にも気づきやすくなります。
- AIへの次の指示が楽になる:落ちたテスト名をそのままAIに渡して「この振る舞いを壊さずに直して」と頼めます。既存テストの渡し方はAIに直させてもリグレッションを出さない既存テストの渡し方で整理しています。
ありがちな落とし穴と、その回避
- 「読みやすくして」と丸ごと頼む:アサーションまで書き換わることがある。範囲を「名前とコメントだけ」と区切る。
- AIがつけた理由をそのまま残す:根拠のない意図コメントは誤解のもと。分からないものは「要確認」で止める。
- 名前に全部詰め込む:条件を5つも6つも並べると、今度は読めなくなる。共通の条件は
describeでまとめ、細かい背景はコメントへ。 - 名前と中身のずれを、名前だけで直す:「マイナスを弾く」テストがマイナスを渡していないなら、直すべきは名前ではなくテストのほうかもしれません。いったん立ち止まります。
- 一度に全部やる:差分が大きくなり、レビューも大変になる。よく落ちるテストから数本ずつで十分です。
明日からやること(小さく始める3つ)
- 最近落ちたテストを1本開いて、名前だけで何が壊れたか言えるか試す:言えなければ、そこが最初の1本です。
- そのテストファイルを、上の頼み方で一覧にしてもらう:まだ書き換えず、「要確認」と「ずれている点」だけ眺めます。
- 確かめた名前だけを書き換えて、名前とコメントだけのコミットにする:実行件数が変わっていないことを確かめて終わりです。
コピーして使う「テストの命名・意図コメント チェックリスト」
# テストの命名・意図コメント チェックリスト
## 1. テスト名
- [ ] 名前だけで「条件・操作・期待」が読み取れるか
- [ ] 関数名をなぞっただけ・番号だけ(test 2 / _3)の名前はないか
- [ ] 「正しく動く」「正常に処理される」で終わっていないか
- [ ] 名前と、実際に確かめている中身が一致しているか
## 2. 意図コメント
- [ ] 「なぜこの値・このケースか」が分かるか(境目・過去の不具合・仕様の出どころ)
- [ ] コードの言い直しだけのコメントはないか
- [ ] AIが推測でつけた理由が残っていないか(分からないものは「要確認」)
## 3. AIに整えさせるとき
- [ ] 範囲を「名前とコメントだけ」と区切って頼んだ
- [ ] 書き換える前に一覧(今の名前/確かめていること/案/ずれ)を出させた
- [ ] 「確かめていること」の読み取りが合っているか、人が中身と照らした
- [ ] 差分で、名前とコメント以外が変わっていないことを確かめた
## 4. 変えたあと
- [ ] スナップショットの差分を確かめてから更新した
- [ ] テスト名で絞り込んで実行している設定・スクリプトがないか検索した
- [ ] 変更の前後で、テストの実行件数が同じだった
最後に
テストの名前を整えても、テストの数は1本も増えません。 でも、いつか夜にCIが赤くなったとき、そのテストを開く誰か——たぶん未来の自分です——が、名前を読んだだけで「ああ、あの境目か」と分かる。それは、落ちたその瞬間のチームを助ける、ちゃんと価値のある仕事です。

一度に全部整えなくて大丈夫です。今日は、最近落ちたテストを1本だけ開いて、名前で何が壊れたか言えるかを試すところから。意図を知っているのはあなたで、言葉を整えるのはAI。その分担で、テストは少しずつ「落ちても読める」ものになっていきます。
よければ、こちらも
- AIのテストそのものを見直すなら AIが書いた単体テストを信用しすぎない|確認ポイント
- テストが本当に意味を持っているか確かめるなら AIのテストはカバレッジが高い|意味のあるテストとの差
- コード側の名前も整えるなら AIに書かせたコードの命名を整える|伝わる名前への直し方
- たまに落ちるテストに悩んでいるなら たまに落ちるテスト(Flaky)の原因をAIに切り分けさせる手順