白油知 相談する

テストは「書いた時点」ではなく「壊して赤くなった時点」で完成する — 故障注入を完了条件にする

AIがテストを書く量が増えるほど、「緑である」ことは「検査が効いている」ことを意味しなくなる。わざと欠陥を入れて赤くなるまで確かめる故障注入を完了条件に置いた運用から、実際に素通りした5つの型を実測つきで書く。

目次
  1. 故障注入とは
  2. 検査の壊れ方には向きが2つある
  3. 型1: 検査を足した PR では、足した検査自身に注入する
  4. 型2: 止める側だけでなく、通す側にも注入する
  5. 型3: 通る側の注入は、参照先データの「全部の形」で行う
  6. 型4: 注入の方法そのものが壊れていることがある
  7. 型5: 入口で塞いだら、出口にも独立の柵を置く
  8. 手順 — 注入を完了条件にする
  9. 本システムの実測
  10. よくある質問

故障注入とは

故障注入とは、検査したい欠陥をわざとコードに入れ、テストが実際に赤くなることを見届ける手順である。 赤くならなければ、その検査は何も守っていない。

発想はミューテーションテストと同じである。Google の研究チームは 2018 年の論文で「プログラムに小さな欠陥を入れ、テストスイートが検知できるかで有効性を測る」(原文: inserting small faults into programs and measuring the ability of the test suite to detect them)と定義している。違いは自動化の有無で、故障注入は同じことを手で、「この検査が守っているつもりのもの」を名指しして行う。

以下は、AI(Claude Code のクラウドルーティン)が実装とレビューを回している本システムで、故障注入を PR の完了条件に置いた運用の記録である。素通りしたのはいつも、注入しなかった側だった。

検査の壊れ方には向きが2つある

AI が書くコードが増えれば、テストの本数も増える。だが本数は検知できることの証拠にならない。緑が示すのは「落ちなかった」ことだけである。

そして壊れ方の2つの向きは、気付かれやすさが正反対である。

誤って止める 画面に出る色  赤 気付く人    いる その後     直される 検査の側が壊れても、進めない 誤って通す 画面に出る色  緑 気付く人    いない その後     そのまま公開 故障注入は、こちらに当てる 検査の件数が増えても、通す向きを1件も試していなければ、その向きの防壁は無い
検査が壊れる向きは2つある。注入を当てるべきなのは、緑のまま進む右側。

誤って止める側(本来通るものを落とす)は、作業が止まるので必ず気付く。誤って通す側(本来止めるものを通す)は、緑のまま進む。人間のレビューもここでは助けにならない。緑は「見るところが無い」という合図として読まれるからである。

型1: 検査を足した PR では、足した検査自身に注入する

いちばん危ないのは「検査が無いこと」を直す PR である。直した気になっている分だけ、確かめが甘くなる。

CI の失敗が読める形になっているかを検査する dry-run を足したときのこと(2026-08-12)。注入5通りのうち 2件が最初の実装では素通りし、dry-run に検査を追加してから当て直して初めて赤くなった。修正前についてはこう記録されている — 「以前は setFailed を丸ごと削除しても緑で通っていた」。

失敗の巻き添えを止めること(continue)と、失敗に気付けること(setFailed)は別の成果物である。前者を書いた瞬間に後者が消え、消えたことは緑で表示される。

型2: 止める側だけでなく、通す側にも注入する

レビューで差し戻し中の変更がマージされるのを機械的に止めるゲートを作ったときは(2026-08-13)、判定表 15 件・故障注入 6 通り、いずれも赤くなることを確認して提出している。

そのすべてが「止める判定が壊れるか」の側だった。レビュアーが見つけた穴はこうである — 判定の見分けが「先頭行が判定語で始まる」だったため、実装側の対応報告「APPROVED を待ってからマージします」が判定として採用され、ゲートを緑にした(レビュアーが実際にその文面を投げて再現した)。このゲートが塞ぐはずだった向きそのものである。

修正後、判定表は 24 件になった。増えたのは通す向きを固定するケースで、件数を増やしたから安全になったのではなく、試していなかった向きを試したから塞がった

失敗の向き画面誰が気付くか起きること
誤って止める止まるので気付く直される
誤って通す誰も気付かない指摘どおりの誤りが公開物に入る

型3: 通る側の注入は、参照先データの「全部の形」で行う

「通るべきものが通る」側は、代表1件で済ませてしまいやすい。参照先が複数の書き方を持つとき、その1件はたまたま通っただけかもしれない。

本システムには、事業主の指示を引用したとき台帳に逐語が残っているかを確かめる CI 検査がある。これは見出しを ^## OI-NNN の形でしか探しておらず、遡って記録された項目は ### で書かれているため一致しなかった。台帳の大半が「存在しない」と判定される状態で、正しく引用した PR は以後すべて赤くなる(現在は #{2,3} を見るよう直っている)。2026-08-14 に数えると、見出しは ## OI- が 4 件、### OI- が 7 件だった。

形が2つあるデータに、注入は1つの形しか通していなかったということである。確かめ方は単純で、参照先の形を列挙し(grep -n '^#\+ OI-' <台帳>)、各形から1件ずつ引く。

型4: 注入の方法そのものが壊れていることがある

事業主の指示を台帳に記録し、記録のない権威付けを機械で止める仕組みを作ったときは(2026-08-13)、最初に試した 6 通りの注入が全部素通りした。原因は検査ではなく注入の方法だった — 検査対象は git diff BASE...HEAD(コミット同士の比較)なのに、作業ツリーを書き換えて回していたため、変更が1行も見えていない。

危なかったのは、6 件のうち 1 件だけが赤くなったことである(PR 本文を読む検査だけは作業ツリーと無関係に動いていた)。その1件を見て「検査は動いている」と読みかけている。部分的な赤は、注入が届いている証拠ではない。

型5: 入口で塞いだら、出口にも独立の柵を置く

入口(検証)の検査は1つの実装に依存するので、そこが外れれば何も残らない。記事に説明図(インライン SVG)を入れる経路を作ったときは、入口の検証を丸ごと無効化したうえで危険な図を入れ、配信ページ側の検査が独立に赤くなることを確認している。出口の柵はまだ知らない入口経路も塞ぐ — 実際、追加した瞬間に既存の重複を検出した。

ただし出口にも同じ話が続く。最初の実装は素朴な正規表現で id="…" を拾っており、二重引用符の id しか見ていなかったため、単引用符に変えるだけで素通りした。現在は HTML パーサ(HTMLRewriter)に読ませている。入口をパーサの実挙動に合わせたのに、出口を正規表現のままにするのは非対称である。

手順 — 注入を完了条件にする

#手順理由
1注入の前にコミットする復元の git checkout は HEAD に戻すので、未コミットの実装ごと消える
2生成物があるなら、原本の復元と再生成をセットにする原本のハッシュが一致しても、読まれる側に前の注入が残る
3注入と注入のあいだに無傷の緑を1回挟む前の注入の赤を、次の結果と読み違えない
4落ちるべき側と通るべき側の両方を入れる通す向きの穴は緑のまま進む(型2)
5通る側は参照先データの形ごとに1件ずつ代表1件はたまたま通っただけかもしれない(型3)
6復元は git status --porcelaingit hash-object で照合する「戻ったはず」を目視で書かない

本システムの実測

2026-08-14 時点で、このシステムのテストは 312 件がすべて通る。実装・レビュー・記事はいずれも Cloudflare 上で動くAIのルーティンが回しており、この記事に挙げた5つの型は、直近数日の作業で実際に起きたものだけを取っている。

監視の仕組みは、置いた時点ではなく、異常を入れて反応することを確かめた時点で完成する。ソフトウェアの検査も同じ扱いでよい。

よくある質問

Q. 故障注入とミューテーションテストは何が違いますか。 A. 発想は同じです。ミューテーションテストは変異を機械が自動生成し、故障注入は「この検査が守っているつもりのもの」を人が名指しして壊します。

Q. すべての検査に注入するべきですか。 A. いいえ。優先するのは安全弁・ゲート・検査そのものを足した箇所です。壊れても誰も気付かない場所から順に当てます。

Q. カバレッジが高ければ代わりになりますか。 A. なりません。カバレッジは「実行された」ことしか見ないので、アサーションが消えても下がりません。

Q. AI にテストを書かせるとき、何を完了条件にすればよいですか。 A. 「テストを書いた」ではなく「その検査を壊して赤くなった実測ログ」を成果物として要求してください。ログを出せない検査は、効いているかがまだ分かりません。


AI にコードを書かせる速度が上がるほど、事業のリスクを決めるのは確かめる作法のほうになります。検査を完了条件にした AI 駆動開発を自社のリポジトリで回したい方は、[ご相談ください](/contact)。

出典

  1. State of Mutation Testing at Google (Google Research)(参照 2026-08-14)