在宣稱某個 bug「已修好」之前,或有人問「這條測試真的會失敗嗎」時使用。做法是把修正還原、跑那一條測試、確認它變紅、再改回來——綠燈只證明測試存在,紅燈才證明它抓得到。
Install
npx skillscat add arthurc02/skillhub/mutation-check Install via the SkillsCat registry.
SKILL.md
突變檢查:把修法弄壞一次
什麼時候跑
- 你打算在 commit message 或回覆裡寫「修好了 X」——那句話的證據就是這一次紅。
- 有人要求確認某條測試有沒有牙齒。
不適用:純文案、純註解、以及本來就沒有斷言可言的變更。
先找 repo 自己的工具
先看環境有沒有把下面的程序做成一個工具:給檔案、要弄壞的那一段、測試命令,它改壞、跑、一定還原並逐位元組確認。有就用它——手動還原最常出的錯是忘了改回來,或改回來時多動了一個字元。下面的手動程序留給沒有這種工具的環境,或工具本身壞掉的時候。
程序
- 確認修正後測試是綠的,並記下跑那一條測試的最小指令:
<test command> <specific test>
例:go test ./internal/foo -run TestBar、npm test -- src/foo.test.ts -t "bar"、pytest tests/test_foo.py::test_bar - 只還原修正的那幾行——不是整個 commit、不是整個檔案。手動改回舊的值/條件/呼叫即可。
- 跑步驟 1 那條指令。
- 斷言它變紅。這一步是全部的重點。
- 變紅 → 測試有牙齒,往下走。
- 還是綠 → 這條測試不驗你以為它在驗的東西。真正的工作還沒開始:先讓它能紅,再談修好。
- 紅在編譯、型別檢查或語法錯誤 → 不算。那只證明你寫壞了語法,不證明測試抓得到行為;換一個仍能編譯、只是行為錯的弄壞法。
- 測試用的 mock 或 fixture 跟被測程式共用同一個假設(例如兩邊都以為參數放在某個欄位)→ 弄壞程式時兩邊一起錯,測試照綠。這時弄壞的對象要改成那個假設本身,並拿真實宿主的一次呼叫對照。
- 把修正改回去,再跑一次確認綠。
- 對那個檔案跑
git diff -- <file>,確認回到步驟 2 之前的狀態,不多不少。
為什麼
改完跑一次測試是綠的,只證明測試存在,不證明它會紅。斷言錯欄位、把待測邏輯 mock 掉、或根本沒被收集到的測試,在修好與沒修好時都是綠的——它對這次修正零資訊量,而它的存在讓人以為有保護。
成本是一次編輯加一次測試執行。code review 看不出來這件事,只有那次紅看得出來。
回報
還原 <哪一行> → <test> FAIL(<斷言訊息>)→ 改回修正 → PASS → git diff 空
沒有那一次 FAIL,就不要寫「修好了」。