はじめに — 緑のバーは、安心していい合図ですか?
AIにテストを書かせると、ほんまに一瞬ですよね。
「このコードのテスト書いて」とお願いするだけで、ファイルがどんと出てくる。流すと、テストランナーが緑のバーを返してくる。カバレッジも、昨日まで40%だったのが一気に85%になっている。なんか、ちゃんと守られてる気がしてくる。
でも、ちょっとだけ立ち止まって考えてみたいんです。
その緑のバーは、「コードが正しい」合図でしょうか。それとも、「コードが動いただけ」の合図でしょうか。
ここがズレてると、けっこう怖いことが起きます。テストはあるのに、バグが本番まですり抜ける。あとで原因を追うと、テスト自体が「実行はしてるけど、何も確かめてなかった」。緑のバーに、ずっと嘘をつかれていた、みたいな状態です。
これ、私の感想だけで言ってるんじゃないんです。2026年6月に出た論文(arXiv:2606.18168「All Smoke, No Alarm」、IEEE AITest 2026採択)が、わりと衝撃的な数字を出しています。
OpenAI Codex / GitHub Copilot / Devin / Cursor / Claude Code という5つのAIエージェントが書いた 86,156件のテストファイルの変更 を、2,807リポジトリにわたって調べたところ、80.2%が「弱い、あるいは明示的なオラクル(=正解の確認)が無い」テストだった。
タイトルの「All Smoke, No Alarm(煙はあるのに、警報は鳴らない)」が、もう本質を言い切ってるなと思います。煙はもくもく出てる。でも、肝心の火災報知器は鳴らない。テストはたくさんある。でも、バグが来ても鳴ってくれない。
この記事は、その「鳴らないテスト」を見分けて、ちゃんと鳴るテストに変えていく話です。具体的にはこんな順番でいきます。
- なぜAIが書くテストは「動くのに守らない」のか、その3つの壊れ方
- カバレッジという数字が、なぜ「テストの良し悪し」を測れないのか
- テストの良し悪しを正面から測る方法 = ミューテーションテスト
- AIにテストを書かせるときの、正しい順番とプロンプト3本
- 落とし穴と、安全に使うための線引き
AI開発にまだ慣れてない方でも置いていかれないように、用語は出てくるたびに噛み砕いていきます。コードもPythonとTypeScriptで、そのまま試せる形で置いておきますね。
まず、言葉をそろえましょう(知らない前提でいきます)
いきなり「ミューテーションが」「オラクルが」と言われても、しんどいですよね。なので、最初に登場人物を整理します。全部、火災報知器のたとえで通します。
- テスト(ユニットテスト):あるコードに値を入れて、出てきた結果が正しいかを自動でチェックする小さなプログラム。火災報知器そのもの、と思ってください。
-
アサーション(assertion):テストの中の「ここがこうなってるはずだ」と断言する1行。
assert 結果 == 100みたいなやつです。これが火災報知器の“鳴る部分” です。アサーションが無いテストは、センサーだけあって音が鳴らない報知器。 - カバレッジ(coverage):テストを走らせたとき、製品コードの何行(何分岐)が実行されたかの割合。「煙が部屋に届いたか」だけを数えてる イメージです。届いたかどうかと、警報が鳴ったかどうかは、別の話ですよね。
-
オラクル(oracle):そのテストにとっての「正解は何か」を知っている人、または仕組みのこと。テストの神様みたいな響きですが、要は 「期待値はこれだ、と決める根拠」 です。
apply_discount(1000, 0.2)の正解は800だ、と決めるのがオラクル。ここが今日いちばん大事な言葉です。 -
ミュータント(mutant):コードにわざと仕込む、小さなバグ。
a + bをa - bに変える、>を>=に変える、みたいな1文字レベルの改変です。 - ミューテーションテスト:そのミュータント(わざとのバグ)を入れたとき、テストが落ちてくれるかを確かめる手法。落ちたら「バグを捕まえた=kill(殺した)」、落ちなかったら「見逃した=survived(生き残った)」。
-
ミューテーションスコア:
殺せたミュータント ÷ 入れたミュータントの割合。これが「火災報知器、ちゃんと鳴りますか?」のテスト です。
ここで一個だけ、腹に落としてほしいことがあります。
コードが実行されること(カバレッジ)と、間違いを検知できること(アサーション)は、全然ちがう。
煙が部屋に入ってきても、報知器が鳴らなきゃ意味がない。カバレッジ85%は「煙が85%の部屋に届いた」だけで、「火事のとき鳴る」保証はどこにも無いんです。
AIのテストが「動くのに守らない」3つの壊れ方
では、AIが書くテストはどう壊れるのか。私が見てきた限り、だいたい3パターンに分かれます。
壊れ方①:アサーションが無い、または弱い
いちばん多いのがこれです。コードは呼ぶ。でも、結果を断言しない。
実はこれ、AI以前からある古い話で、マーチン・ファウラーが「Assertion Free Testing(アサーションの無いテスト)」という有名なエッセイで書いています。あるプロジェクトが「全public関数にJUnitテストがあります」と緑のバーを誇らしげに見せたのに、テストの中にアサーションが1つも無かった、という逸話です。アサーションが無ければ、テストは例外で落ちない限り永遠に緑。カバレッジ100%だって作れてしまう。
# 弱いテスト:呼ぶだけ。何も断言していない(=鳴らない報知器)
def test_apply_discount_weak():
result = apply_discount(1000, 0.2)
assert result is not None # None じゃなければ何でも通る
apply_discount が 800 を返そうが 7 を返そうが、このテストは通ります。煙センサーはあるのに、音を鳴らす配線がつながってない状態です。
# 強いテスト:何が正しいかを断言している(=鳴る報知器)
def test_apply_discount_strong():
assert apply_discount(1000, 0.2) == 800
assert apply_discount(0, 0.5) == 0
assert apply_discount(1000, 0) == 1000
壊れ方②:トートロジー(実装を、そのまま正解にしてしまう)
これがいちばん厄介で、見た目はちゃんとしてるのに中身が空っぽ、というやつです。
# トートロジー:実装そのものを期待値に使っている
def test_calc_total_tautology():
cart = [{"price": 100, "qty": 3}]
expected = calc_total(cart) # ← テスト対象を呼んで「正解」にしている
assert calc_total(cart) == expected
これ、絶対に落ちません。だって「calc_total の結果は calc_total の結果と等しい」と言ってるだけですから。仮に calc_total に「数量を掛け忘れる」というバグがあっても、バグった答えがそのまま「正解」になる。バグごと、まるっと固定してしまう んです。
なんでAIがこれをやりがちか。理由はシンプルで、AIは「仕様(こうあるべき)」じゃなくて「コード(いま、こう動いている)」を見てテストを書くから です。目の前のコードの挙動を観察して、それをそのまま期待値にする。だからコードが間違っていても、間違いごとコピーしてしまう。
実際、2024年末の研究(arXiv:2412.14137)でも、LLMベースのテスト生成ツールのオラクルが「誤った挙動をそのまま是認したり、バグを暴くテストの方を棄却したりする」傾向が報告されています。正解を知らないまま正解を書こうとすると、こうなるんですね。
壊れ方③:ハッピーパスしか通らない
3つめは、正常系だけ書いて、異常系・境界値を書かないパターンです。
# ハッピーパスだけ:気持ちのいい入力しか試していない
def test_divide_happy():
assert divide(10, 2) == 5
divide(10, 0)(ゼロ割り)は? マイナスは? 文字列が来たら? ——バグって、だいたい「気持ちのいい入力」の外側に潜んでます。境界(0、空配列、最大値、最小値)と異常(不正な型、None、例外)こそ報知器を置くべき場所なのに、AIは頼まないと、たいてい真ん中の安全地帯しかテストしてくれません。
この3つに共通するのは、「コードを実行はしている(だからカバレッジは上がる)」のに、「正しさは確かめていない(だから守ってはいない)」 という一点です。
カバレッジが「品質」を測れない、構造的な理由
ここで、さっきの違和感を正面から言語化します。
カバレッジは「実行された行」を数える指標です。アサーションが強いか弱いかは、1ミリも見ていません。 だから、弱いテストでもカバレッジは平気で上がる。むしろAIは「カバレッジを上げてください」と言われると、アサーションを増やすんじゃなくて「とにかくコードを通る入力」を増やしがちです。これが、数字だけ立派な“飾りのテスト”が生まれる仕組みです。
メタ(Facebook)のエンジニアリングブログ(2025年9月、ミューテーションテストの大規模実用化の記事)も、まさにここを突いています。
構造的なカバレッジ基準(statement coverage や branch coverage)は、コードの行が実行されたかどうかしか示さない。行が実行されてもバグを検知できないことがある。
つまり、こういう絵が普通に起きます。
- カバレッジ 95% / でも実際にバグを捕まえる力(ミューテーションスコア)は 30%
数字は95点なのに、実力は30点。報知器が95%の部屋にあるのに、火をつけても3割しか鳴らない。これを「品質保証できてます」と言うのは、ちょっと無理がありますよね。
誤解しないでほしいのは、カバレッジが無意味なわけじゃない ということです。カバレッジは「まだ一度も触られてない場所」を教えてくれる、最低限の衛生チェックとしては有効です。ファウラーも補足で「アサーションが無くても、null参照みたいな実行時エラーは見つかることはある」と言っています。
ただ、カバレッジは 品質の“下限”を見るもの であって、品質の“高さ”を保証するものじゃない。ここを混同したまま「カバレッジ80%達成、テスト完了」とやると、静かに事故ります。
本命:ミューテーションテスト — わざとバグを入れて、報知器が鳴るか試す
じゃあ、テストの「良し悪し」をどう測るのか。ここで主役の登場です。ミューテーションテスト です。
考え方は、拍子抜けするくらいシンプルです。
- 製品コードに、小さなバグ(ミュータント)をわざと1個入れる。例:
a + b→a - b。 - その状態でテストを全部流す。
- どれかのテストが落ちたら、そのバグは捕まえられた=kill。
- 全部のテストが通ってしまったら、バグは見逃された=survived(生き残り)。
- これを何十・何百ものミュータントで繰り返して、
kill ÷ 全体= ミューテーションスコア を出す。
要は、「火災報知器の点検で、わざと煙を焚いてみる」 のと同じです。鳴れば合格、鳴らなければ、その報知器(テスト)は飾りだったとバレる。だからミューテーションテストのことを、私は「テストのためのテスト」と呼んでいます。
メタのブログも、ミューテーションテストを「(数十年の研究が一貫して示してきた)最も強力なテストの形」と表現していました。同時に「ミューテーションテストはそれ単体では成立しない。先にテストが存在していないと始まらない」とも。あくまで 既にあるテストの強さを測って、弱いアサーションを炙り出す装置 なんですね。
道具(2026年時点)
| 言語 | ツール | ひとこと |
|---|---|---|
| Python | mutmut |
mutmut run で実行、mutmut browse で生き残りを確認。pytestと相性が良い |
| JS / TS / .NET | Stryker | ミューテーション種が豊富、Jest / Vitest 対応、変更分だけ回すincrementalモードあり |
| Java | PIT | JVM系の定番 |
実際にやってみる(Python / mutmut)
さっきの「弱いテスト」に、mutmutをかけてみる想定で見てみましょう。対象はこんなコードだとします。
# shop.py
def apply_discount(price: int, rate: float) -> int:
if rate < 0 or rate > 1:
raise ValueError("rate must be between 0 and 1")
return int(price - price * rate)
mutmutを動かします。
# インストールして、対象とテストコマンドを指定して実行
pip install mutmut
mutmut run --paths-to-mutate shop.py --runner "pytest -q"
# 生き残ったミュータント(=テストが見逃したバグ)を一覧で見る
mutmut results
mutmut browse
もしテストが「壊れ方①」の弱いやつ(assert result is not None)だけだと、こんな報告が返ってきます。
survived: rate < 0 → rate <= 0 に変えても、テストは全部通った
survived: price - price * rate → price + price * rate に変えても通った
「鳴らへんかったで」と教えてくれてるわけです。ここで初めて、自分のテストが報知器として機能してなかったと分かる。で、アサーションを足して、もう一度回す。
def test_apply_discount_kills_mutants():
assert apply_discount(1000, 0.2) == 800 # 「-」を「+」に変えたら 1200 になって落ちる→kill
assert apply_discount(1000, 0) == 1000
# 境界:rate がちょうど 0 / 1 は許可、その外は例外
assert apply_discount(500, 1) == 0
import pytest
with pytest.raises(ValueError):
apply_discount(500, 1.5) # 「>」を「>=」に変えたら例外が出なくなって落ちる→kill
再実行してミューテーションスコアが上がれば、それは「報知器がちゃんと鳴るようになった」という、目に見える前進です。カバレッジと違って、ごまかしが効きません。
JS / TS なら Stryker
TypeScriptでも考え方は同じです。設定ファイルを置いて回すだけ。
// stryker.conf.js
/** @type {import('@stryker-mutator/api/core').PartialStrykerOptions} */
module.exports = {
testRunner: "vitest",
coverageAnalysis: "perTest",
mutate: ["src/**/*.ts", "!src/**/*.test.ts"],
thresholds: { high: 80, low: 60, break: 50 }, // スコアが50%未満ならCIを落とす
};
npx stryker run
# → killed / survived / no coverage を色分けしたレポートが出る
thresholds.break を決めておくと、「ミューテーションスコアが一定を下回ったらビルドを失敗させる」ができます。カバレッジゲートの、ひとつ上の世界ですね。
テストオラクル問題 — ここだけは、人間が握る
さて、ここまで来ると、ひとつの壁にぶつかります。
ミュータントを入れて回すのは機械が得意。アサーションの“形”を書くのもAIが得意。でも「apply_discount(1000, 0.2) の正解は本当に 800 なのか?」を決めるのは、誰の仕事でしょう。
これが、ソフトウェアテストの世界で昔から「テストオラクル問題」と呼ばれてきた、いちばん難しいところです。テストの仕組み(How)はいくらでも自動化できる。でも「何が正しい答えなのか(What / Why)」は、仕様や意図を知っている人間にしか決められない。
ここでAIに「正解も推測しといて」とやると、壊れ方②のトートロジーに逆戻りです。AIは目の前のコードを見て「たぶんこれが正解」と埋めるので、コードが間違ってたら間違いが正解になる。だから、
オラクル(正解の根拠)は人間が与える。テストの仕組みはAIに書かせる。
この分担が、今日いちばん持って帰ってほしい一行です。表にするとこうなります。
| 工程 | 人間(What / Why) | AI(How) |
|---|---|---|
| 守りたい挙動を決める | ◎ 仕様・意図・正解を決める | △ 候補出しの補助 |
| 境界値・異常系の洗い出し | ◎ 抜けの最終判断 | ○ 候補を大量に出す |
| テストコードを書く | △ レビュー | ◎ 仕組みを書く |
| アサーションの強さ点検 | ◎ 何を検証してないか判断 | ○ 弱い箇所の指摘 |
| ミューテーションで採点 | ○ しきい値を決める | ◎ 実行・集計 |
| 生き残りバグの解釈 | ◎ 直す/等価と判断 | ○ 説明の下書き |
AIは優秀な“テスト職人”です。でも、何を守るべきかの設計図は、人間が描く。職人に設計まで丸投げすると、立派だけど誰も住めない家が建ってしまう、という感じですね。
AIにテストを書かせる「正しい順番」=計測駆動の品質ループ
役割分担が決まったら、あとは順番です。私はこれを「計測駆動の品質ループ」と呼んでいます。5ステップです。
- 人間が、守りたい挙動と境界・異常系を先に決める。 ここがオラクルの種。「割引率は0〜1、それ以外は例外」「空カートは0円」みたいに、コードを見る前に言語化する。
- AIにテストを書かせる。 ただし「実装からではなく、この仕様から書いて」と渡す。
- アサーションの強さをレビューする。 「このテスト、何を検証してない?」をAIにも人間にも問う。
- ミューテーションテストで採点する。 survived(生き残り)が出たら、そこが報知器の穴。
- CIゲートを、カバレッジじゃなくミューテーションスコアにする。 ただし全部に回すと重いので、変更があったファイルや重要モジュールだけ に絞る。
ステップ5を、GitHub Actionsで雑に書くとこんな感じです。
# .github/workflows/mutation-gate.yml
name: mutation-gate
on: [pull_request]
jobs:
mutation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- run: pip install pytest mutmut
# 変更があった .py だけをミューテーション対象にする(全体は重いので絞る)
- name: Run mutation testing on changed files
run: |
CHANGED=$(git diff --name-only origin/${{ github.base_ref }}... \
| grep -E '\.py$' | grep -v '_test\.py$' || true)
if [ -z "$CHANGED" ]; then echo "no python changes"; exit 0; fi
echo "mutating: $CHANGED"
mutmut run --paths-to-mutate "$CHANGED" --runner "pytest -q"
# 生き残りが多すぎたら落とす(しきい値は人間が決める)
- name: Check survivors
run: |
mutmut results
SURVIVED=$(mutmut result-ids survived | wc -w | tr -d ' ')
echo "survived mutants: $SURVIVED"
if [ "$SURVIVED" -gt 5 ]; then
echo "::error::Too many survived mutants ($SURVIVED). Strengthen your assertions."
exit 1
fi
ポイントは、しきい値(いくつ生き残ったら落とすか)は人間が決める ことと、変更分だけに絞ってコストを抑える ことです。いきなり全社のコードに100%を求めると、計算時間で死にます。まずは「お金・安全・データに関わる重要モジュール」から始めるのが現実的です。
そのまま使えるプロンプト例3本
ここからは、AIに頼むときの実物です。3本とも、最終判断は人間がする 前提で作っています。コピペして、ダミー部分を自分のコードに置き換えてください。
プロンプト①:境界値・異常系の洗い出し(コードからではなく、仕様から)
あなたはテスト設計のレビュアーです。
以下の「関数の仕様」だけを根拠に、テストすべきケースを洗い出してください。
※実装コードは見ずに、仕様から考えること。
# 仕様
apply_discount(price, rate):
- price は 0 以上の整数(円)
- rate は 0.0〜1.0 の割合
- 戻り値は割引後の金額(整数、端数は切り捨て)
- rate が範囲外なら ValueError
# 出力形式(表)
| 分類(正常/境界/異常) | 入力 | 期待値または期待例外 | このケースで守りたい挙動 |
正常系だけでなく、境界(0, 1, 端数が出る値)と
異常(範囲外, 負の価格, 型違い)を必ず含めること。
抜けがありそうな観点も最後に箇条書きで指摘してください。
仕様から考えさせるのが肝です。これで、壊れ方③(ハッピーパスだけ)をかなり潰せます。
プロンプト②:オラクルを明示したテスト生成(実装のコピー禁止)
次の仕様とテストケース表をもとに、pytest のテストを書いてください。
# 厳守ルール
- 期待値は、私が表で与えた値だけを使うこと。
テスト対象の関数を呼んで、その結果を期待値にしないこと(トートロジー禁止)。
- 各 assert の横に、「この assert がどのバグを捕まえるか」をコメントで書くこと。
- 例外ケースは pytest.raises で明示すること。
- マジックナンバーには意味をコメントで添えること。
# 仕様
(プロンプト①の仕様を貼る)
# テストケース表
(プロンプト①の出力を貼る)
「実装を呼んで期待値にするな」と明示することで、壊れ方②(トートロジー)を構造的に防ぎます。「各assertがどのバグを捕まえるか書け」と言うと、アサーションが自然と強くなります。
プロンプト③:テスト品質レビュー(何を検証してないか/生き残りの埋め方)
以下のテストコードと、ミューテーションテストで「生き残ったミュータント」の一覧を渡します。
あなたの仕事は、テストの“穴”を見つけることです。
# やってほしいこと
1. 各生き残りミュータントについて、なぜ今のテストが捕まえられないかを説明する。
2. それを捕まえるための追加 assert を提案する(期待値の根拠も書く)。
3. 「等価ミュータント(挙動が本当に変わらず、殺せないのが正しいもの)」の
可能性があるものは、そう指摘して人間の確認に回す。
→ 確信が持てないものは断定せず「要確認」と書くこと。
# テストコード
(ここに貼る)
# 生き残ったミュータント
(mutmut results / stryker のレポートを貼る)
ここでも、AIに「断定させない」のが大事です。等価ミュータントかどうかは人間が決める。AIは候補と理由を出す係に徹してもらいます。
落とし穴と、ミューテーションテスト自体の注意点
便利な道具ほど、雑に使うと事故ります。よくある落とし穴を6つと、ミューテーションテスト固有の注意を置いておきます。
| # | 落とし穴 | どうなるか |
|---|---|---|
| 1 | カバレッジ100%で安心する | 実行されただけ。鳴らない報知器が満室になる |
| 2 | アサーション無しテストを量産 | 緑のバーが嘘をつき始める |
| 3 | 実装をコピーした期待値(トートロジー) | バグごと固定。永遠に落ちない |
| 4 | ハッピーパスしか書かない | 境界・異常という“バグの巣”が無防備 |
| 5 | オラクル(正解)までAIに丸投げ | 間違いが正解になる |
| 6 | ミューテーションスコア100%を盲信 | 100%でもバグ0の保証ではない |
そして、ミューテーションテストにも弱点があります。ここを知らずに使うと、逆に振り回されます。
- 等価ミュータント(equivalent mutant):コードを変えたのに、挙動がまったく変わらないミュータントがあります(例:絶対に通らない分岐の中の変更)。これは「殺せない」のが正しいのに、レポート上は survived として残る。全部を0にしようとすると、この幻のバグ退治に時間を溶かします。 「これは等価」と人間が判断して除外していい。
- 計算コストが高い:ミュータントを何百個も作って毎回テストを回すので、重い。だから 変更分・重要モジュールに絞る のが鉄則です。全コードに毎回フルでかけるものではありません。
- スコアは万能じゃない:ミューテーションスコア80〜90%台はとても良い目安ですが、100%でもバグが無い証明にはなりません。プロパティベーステストや統合テスト、人間のレビューと組み合わせるものです。
撤退ラインも決めておきましょう。
- スコアが頭打ちになったら、追うのをやめる。 90%超を95%にする労力より、別モジュールの50%を80%にする方が価値が高いことが多いです。
- 等価ミュータントだらけのモジュールは、ミューテーション対象から外す。 無理に追わない。
- 重要度が低いコードは、カバレッジの最低限だけで十分。 全部に同じ厳しさを求めない。
安全に使うために — テストデータと不可逆操作
最後に、安全の話を少しだけ。テストまわりは、地味に事故が起きやすい場所です。
-
テストデータに、本物の個人情報や秘密情報を入れない。 AIにテストを書かせるとき、実データをそのまま貼ると「AIに渡す=外に出す」ことになります。氏名・メール・APIキー・本番のレコードは、必ずダミー(
user@example.com、test-token-xxxxなど)に置き換える。 - テストが、不可逆な操作を本物に向けて叩かないようにする。 本番DBへの書き込み、課金、メール送信、データ削除——こういう「戻せない操作」は、テストではモックやサンドボックスに逃がす。AIが生成したテストが、うっかり本番のエンドポイントを叩いていないか、人間が必ず確認する。
- 外部から来たテキストは“データ”として扱う。 Issueやログをそのままプロンプトに混ぜると、そこに紛れた指示にAIが反応することがあります(プロンプトインジェクション)。外部入力は命令ではなくデータとして囲って渡す。
このあたりは、テストの良し悪し以前の「戸締まり」です。良いテストを書く前に、鍵を閉めておきましょう。
おわりに — 緑のバーを、明日の自分への約束に変える
ここまでお付き合いいただいて、ありがとうございます。
最後に、ひとつだけ。私がこのテーマを大事だと思う理由は、テストって結局「未来の自分との約束」だからなんです。
弱いテストは、緑のバーで「大丈夫だよ」と言ってくれる。でもそれは、何も確かめていない“空っぽの安心”です。半年後、本番でバグが出たとき、その緑のバーは何も守ってくれない。むしろ「テストあったのに、なんで」と、過去の自分を責めたくなる。
でも、ここで過去の自分を責めるのは、ちょっと違うと思っていて。弱いテストを書いてしまったのは、ただ「アサーションの強さ」という見方を、まだ持ってなかっただけです。
強いテストは、逆です。バグが入り込もうとした瞬間に、報知器みたいに鳴ってくれる。「ここ、変わってるで」と教えてくれる。それは、未来の自分への置き手紙であり、「あの時ちゃんと鳴るようにしといてくれて、あざっす」 と言える贈り物になる。責める道具じゃなくて、思いやりの道具なんです。
そして、ちゃんと鳴るテスト群は、放っておいても消えません。コードを書き換えるたびに、何度でも守ってくれる。これは積み上がっていく 資産 です。書くのはAI(How)でいい。でも「何を守るか(What / Why)」を決める力は、AIに奪われない。むしろAI時代に、いちばん値上がりするスキルだと思います。
なので、もし今日ひとつだけ試すなら、これを。
- いちばん大事な関数を1つ選ぶ(お金・データ・安全に関わるやつ)。
- mutmut か Stryker を1回だけ回してみる。 スコアが想像より低くて、たぶん驚きます。
- 生き残ったミュータントを1個選んで、それを殺すアサーションを1行足す。
- CIに、変更分だけのミューテーションチェックを1本入れる。
たった1行のアサーションが、半年後のあなたを救うかもしれません。緑のバーを、ただの色から、ちゃんと意味のある約束に変えていきましょう。
それでは、今日もご安全に。