動手抓出你的綠燈謊言

#QA 思維 #AI #測試策略 #QA 學習

我把自己的程式改錯,七個測試卻全綠。如果你也想知道自己的測試是不是正在說謊,這篇教你動手把它抓出來。 上一篇〈我憑什麼相信綠燈〉講的是「為什麼綠燈會騙人」;這篇只做一件事——動手,把你自己專案裡的綠燈謊言挖出來。 用的技術叫 mutation testing (突變測試)。它的邏輯是反過來的——不問「測試會不會通過」,而是故意把程式改錯,看測試殺不殺得掉這個壞掉的版本。改錯後測試變紅,叫「殺掉」;改錯後測試照樣全綠,叫「存活」。一個存活的 mutant,就是你測試網上的一個洞。 下面三種做法,從手動到自動,難度遞增,威力也遞增。 做法一:手動跑一次(最該先做的) 不要急著上工具。第一次請手動跑,因為你要親眼看到「綠燈不變」那一刻,才會真的不舒服。 我在 toc.js(把文章標題切成目錄的小模組)上手動植入三個,結果是這樣: | Mutant | 我改了什麼 | 測試反應 | | | | | | M1 | 標題比對 {2,3} → {2,4}(誤收 h4) | 🟢 七個全綠, 存活 | | M2 | {2,3} → {1,3}(誤收 h1) | 🔴 被殺 | | M3 | 空白轉連字號時不保留長度 | 🔴 被殺 | 殺掉兩個,存活一個。M1 存活的意思是:「目錄誤收 h4」這個會壞的行為,我的測試完全沉默——因為我從沒寫過一個餵 h4 的案例。 幾個最值得試的 mutant 類型,套在任何專案都行: 比較符號:< ↔ <=、 ↔ = 邏輯運算:&& ↔ || 邊界數字:2,3 ↔ 2,4、0 ↔ 1 直接刪一行,或把回傳值改成 null 做法二:讓 Claude Code 自動跑 手動跑過一次、抓到感覺之後,把這件苦工交給 AI。重點是—— 開一段新的對話 ,只丟程式碼進去,下這種指令: 幾秒鐘,它做完你手動半天的事,還會把存活的 mutant 一條條攤給你看。 ⚠️ 別在「剛寫完這支程式的那段對話」裡叫它做這件事。 帶著同一套假設的腦袋,既寫程式又寫測試,只會把你的盲點自動化一遍——它跟你一樣想不到 h4。要讓驗證有意義,就換一段乾淨的對話,只給程式碼,不給你的假設。 做法三:上 Stryker(可進 CI、出報告) 要把這件事變成團隊常態、掛進 CI,就用正式工具。JS/Vitest 專案用 Stryker : 建一個 stryker.config.json: 跑: 它會自動生成上百個 mutant、逐一驗,最後給你一個 mutation score ,並輸出 HTML 報告,紅色標出每個存活 mutant 在第幾行。比手動精準、可重複,也能設門檻擋 PR。 mutation score 怎麼看 跑完你會拿到一個分數,例如我那 toc.js 是 2/3。但別把它當成另一個要刷到 100% 的數字——那只會逼出一堆為了殺 mutant 而寫的爛測試。 真正該做的,是去看 存活清單 。每一個活著的 mutant,都是在問你同一句話:「這個行為要是真的壞了,誰會發現?」如果答案是「沒有人」,那就是你下一個該補的測試——不是因為要衝分數,是因為那裡真的沒人守。 從一個你最在乎、最不能壞的模組開始,手動跑一次。你會比看任何覆蓋率數字都更清楚,自己的測試到底守住了什麼。