一場關於「AI 生成的測試,誰來驗證?」的實驗
這場演講在談什麼
英國 Bluefruit Software 的創辦人 Paul Massie 做了一個很誠實的實驗。
他用 vibe coding 工具在三分鐘內生出一個「兒童 ibuprofen 劑量計算器」,然後花了接下來的兩個小時,試圖把它變成一個他敢交給病人用的東西。
過程中他用了兩個工具:BDD 和突變測試(Mutation Testing)。結論不是「AI coding 很安全」,也不是「AI coding 不能用」,而是一個更有價值的東西——一套讓 AI 產出可被驗證的分層防護,以及一個他自己都沒預料到的轉折。
這個轉折,正好命中了 AI 時代測試最核心的難題。
Bluefruit 是一家成立 25 年、約 60–70 人的嵌入式軟體公司,客戶橫跨醫療、功能安全、航太、國防——全都是高度受規範的領域。這件事很重要:他不是在實驗室裡玩,他是真的要把這些東西交出去。
第一幕:三分鐘的奇蹟
Paul 用 bolt.new 下了一段 prompt:
做一個 ibuprofen 劑量計算器,詢問病人年齡以判斷是兒童或成人,輸入體重與症狀,自動計算合適劑量並提供適當警語。
三分鐘後,網站生出來了。前端、後端資料庫、部署,全部完成。輸入年齡體重症狀,它回你建議劑量、服用頻率、警語。
好處是真的好
- 生產力:三分鐘 vs. 兩三天
- 創造力:可以一口氣生五個原型丟給使用者試,而且常常出現你沒想到的解法
- 原型設計:比 Figma 的點擊式原型更進一步——這是可以真的動的軟體,回饋品質完全不同
但代價也是真的
Paul 列了四個問題,其中第三個是重點:
- 缺乏透明度——你不知道它到底做了什麼
- 沒有追溯性——需求、規格、程式碼、測試之間的連結斷掉了
- 不安全的假設——這是最致命的
- 不符合法規——在醫療領域,這代表不能出貨
關於第三點,他講了一段我覺得整場最有份量的話:
身為工程師,我們整天都在做決策。有些是小的技術決策,靠經驗判斷;有些是高層次的決策,要跟使用者和利害關係人討論。做決策、而且做對決策,就是我們被付錢做的事。
而 AI 做了成千上萬個決策——沒有問任何人、沒有 check in、沒有確認假設對不對。
現場投票:「你敢用它算你小孩的藥量嗎?(1–10 分)」平均約 3 分。
關鍵洞察:AI 就像你團隊裡的資淺工程師
這是整場演講的樞紐。
Paul 說,當他把這四個缺點列出來的時候,他發現一件事:這些問題我太熟悉了。
不透明、不追溯、自己亂做假設、不遵守規範——這正是他 25 年來帶資淺工程師時,一再遇到的同一組問題。有時候資深工程師也會犯。
那麼問題就變成:我們用來讓資淺工程師不出包的那套工具箱,能不能直接拿來用在 AI 上?
這個框架之所以有力,是因為它把「AI 該怎麼管」從一個全新的、令人焦慮的問題,翻譯成一個軟體工程界已經處理了三十年的舊問題。
第一層:標準(Standards)
依領域不同:IEC 61508(功能安全)、IEC 62304 / 82304(醫療)、DO-178(航太)。
這些標準的核心價值是什麼?
決策的追溯性。 從 user needs → 軟體需求 → 設計 → 詳細設計 → 程式碼,V model 的每一層都有對應的驗證(verification),最後對著 user needs 做確效(validation)。加上風險管理,以及全程可稽核。
但標準單獨用不夠。 Paul 講得很直白:
- 標準能防止混亂,但也會拖慢創新——而創新本身是高品質軟體的一部分
- 更糟的是打勾心態(tick-box mentality):團隊照著流程做了,但沒有交付出流程原本想要的品質
他舉的例子非常具體:很多團隊是在程式碼寫完之後才補單元測試。覆蓋率數字有了,稽核通過了,但那些測試根本沒有效果。
記住這個例子,等一下突變測試會回頭把它打爆。
第二層:敏捷與 BDD
敏捷實踐帶來的是平衡:在安全與速度之間,同時把品質內建在做法裡,而不是事後檢查。TDD 就是最好的例子——它讓單元測試在寫的當下就有效。
在醫療領域,這不是想像。AAMI TIR45 這份 2012 年的指引文件,明確說明如何用敏捷實踐去滿足法規期待。BDD 產出的規格與測試,是可以放進法規文件包的。
BDD 的兩個面向
技術面:可執行的需求模型
用 Given / When / Then 寫成自然語言的規格,然後自動化它。BDD 最聰明的一手是:它把「規格」和「測試」合併成同一個 artifact。所以你隨時可以跑一次,看到目前的程式碼跟大家講好的行為,有多少對得上、多少對不上。
協作面:Three Amigos
business、dev、tester 坐下來一起談出驗收條件。這件事沒有被 AI 取代,反而更重要——因為它是人類定義正確行為的場合。
Paul 的實驗流程
- 準備 PRD(3 個 user needs、20 條需求)
- 丟給 Claude Code,請它產出 BDD 規格檔——帶需求編號,可回溯 PRD
- 自動化:產生 55 個情境,52 個通過
- 產出 living documentation 與覆蓋率報告,跟程式碼一起放進 git
第 3 步是關鍵。Paul 說了一句很值得畫線的話:
Bluefruit 所有專案都做 BDD,但我們不一定會自動化——因為要自動化那些測試的負擔太大了。
自動化成本一直是 BDD 落地最大的阻力。這正是 AI 幫上最大忙的地方。
而「跟程式碼一起進 git」的意義是:任何一個 release,你都能翻出當時的規格、測試步驟、測試結果,三者同步。這在受規範領域是硬需求。
還有一個副作用:那三個失敗的測試,抓到了真 bug。所以剛剛投低分的人,直覺是對的。
進度盤點
- 透明度 ✅ living documentation
- 追溯性 ✅ PRD → 規格 → 測試 → 程式碼
- 不安全的假設 ✅ 有護欄了,AI 自作主張的地方會顯示為「與規格不符」
- 法規合規 🟡 有了驗證框架,再疊上 TDD、code review 等實踐,算是好的開始
現場再投票一次:從 3 分升到 4.5–5 分。
轉折:他不信任這些測試
這是整場演講最有價值的一段,也是我認為所有在推 AI + BDD 的人都該停下來想的一段。
Paul 說,他自己還是不滿意。為什麼?
我們用 Claude Code 產生了程式碼,也用 Claude Code 產生了測試。這中間缺乏獨立性。
當你真的去看那些測試,會擔心 AI 產生幻覺,或者它太想取悅你、給你它認為你想看到的結果。
而 BDD 這整套工作流,非常依賴你信任那些測試。
所以我的結論是:我不信任這些測試。
他自己形容這是個 plot twist:BDD 不是銀彈。
這其實是「Oracle Problem」
用測試理論的語言講:當 AI 同時產生實作與測試,誰來定義什麼是正確的行為?
測試本來的功能,是提供一個獨立於實作的正確性判準(oracle)。一旦兩者來自同一個模型、同一次推理、同一組被誤解的假設,測試就從「驗證」退化成「複述」。它們會漂亮地全部通過——通過的是 AI 對需求的理解,不是需求本身。
這也是 AI 時代最典型的「驗證瓶頸」:程式碼生成快了一百倍,但瓶頸只是往下游移動到審查、驗證與理解。而如果連驗證工具本身都是 AI 生的,瓶頸沒有被解開,只是被藏起來了。
你需要一個 AI 無法說服的東西。
第三層:突變測試(Mutation Testing)
Paul 回頭去翻他管資淺工程師的工具箱,找到了這個他自己也不常用的技術。
它怎麼運作
突變測試的目標,是測試你的測試有多有效。
工具會掃過你的整個 codebase,在每一個分支、每一個 if、每一個迴圈,注入一個 bug(稱為 mutant)。然後跑你的測試,看測試抓到了幾隻。
抓到的比例,就是 mutation score。
這跟覆蓋率的差別是根本性的:覆蓋率只告訴你測試「碰過」多少程式碼,不告訴你測試「檢查」了什麼。那些事後補寫的單元測試,覆蓋率可以很漂亮,mutation score 會很難看。
實驗結果
Paul 用 Stryker 跑他那個 ibuprofen 計算器:
- 產生 141 個 mutants
- 原本那套 AI 生的 BDD 測試,只抓到 30%
一個這麼小、這麼簡單的 codebase,30%。他的不信任是有根據的。
接著他做了一件很聰明的事:把 Stryker 交給 Claude Code,讓它自己跑 feedback loop——診斷為什麼這些測試抓不到 mutants,然後修。(Claude Code 是 agent,可以自己列 to-do、自己用工具、自己迭代。)
需要人在旁邊引導,花了一段時間,最後拉到 80%。漏掉的多半是字串常數這類本來就會變動、可以理解的東西。
它揪出了什麼:問題貫穿整個 V Model
這段是我覺得最精彩的。突變測試找到的問題,不只在測試層:
PRD 有缺口。 六個月以下嬰兒的年齡區間,需求文件根本沒寫清楚。而 AI 沒有抗議、沒有提問、沒有標記——它就自己猜了一個。
我不能接受這樣。AI 很能接受。是一直到跑了突變測試,這個缺口才浮現出來。
規格有缺口。 從 PRD 生出來的 Given/When/Then 沒有他以為的那麼完整。
測試有缺口。 這是預期中的。
程式碼也有問題。 它找到了 dead code——因為工具往那段死碼裡注入 bug,而測試永遠不可能抓到。
換句話說,一個純粹的、非 AI 的、機械式的工具,反向照出了從需求到實作每一層的破洞。這是我認為這場演講最值得帶走的一件事。
成本帳:慢了幾倍,但還是快
| 階段 | 耗時 | 累計 |
|---|---|---|
| Vibe coding | 3 分鐘 | 3 分鐘 |
| + BDD 規格、自動化、文件 | +20–30 分鐘 | ~30 分鐘 |
| + 突變測試與迭代修正 | +90 分鐘 | ~2 小時 |
慢了 40 倍。
但原本手工做這件事要 兩到三天。
這個帳算得很清楚:AI 的價值不是「三分鐘做完」,而是「兩小時做完一件本來要三天、而且品質更高的事」。省下來的時間,不是拿去多寫功能,是拿去做驗證。
最終投票:又往上升了一些,但仍然有很大的分歧——包括 Paul 自己。他沒有假裝問題解決了。
Q&A 裡的重點
Q:有跟人類團隊做對照組嗎?
沒有,但他引用了一篇比較 test-first 與 test-last 的論文(用 mutation score 當作測試有效性的指標):
- test-last:平均約 60%,而且離散度極大——資淺開發者只有 20–30%
- test-first:平均 80 多分,而且分佈非常集中,大家都在 80 幾
第二點比第一點更有意思:TDD 的價值不只是平均值高,是它壓縮了品質的變異數。它讓「這段程式碼的測試好不好」不再取決於是誰寫的。
Q:突變測試要一直留在流程裡嗎?
要。提問者的觀察很尖銳:就算一開始測試寫得很好,只要你叫 AI「讓這些測試通過」,它試不出來的時候,就會去改測試把它變綠。
Paul 認同:「確實有作弊的傾向。」
但突變測試很慢(一次只能注入一個 mutant 跑一輪,不可能 141 個一起注入),所以不適合放在每次 commit 的 pipeline,比較適合當作低頻率的定期檢查。
Q:PRD 有大小上限嗎?
有,受 context window 限制。解法是拆成元件,或改用 context window 更大的模型(他提到 Gemini)。但追問者指出真正的難題:如果需求是橫切整個系統的,拆開之後一致性怎麼維持? 這題沒有好答案。
Q:導入最大的阻力是什麼?
三個:
- 讓開發者上車——他觀察到很多人一兩次壞經驗就全盤否定。但下 prompt、把 AI 拉回正軌,是一組要練的新技能,需要撐過去。
- 讓客戶上車——資料留存、程式碼會不會被拿去訓練,這些疑慮要處理。
- 確保淨產出是正的——不能為了用 AI 而用 AI。
然後他講了一句我認為是整場最重要的定位:
我研究這件事的主要動機,其實不是生產力。是我們能不能藉此把軟體品質推上去——去做那些我們從來沒有餘裕、沒有資源去做的實踐。
例如,把所有 BDD 測試都自動化。我們從來沒有足夠的產能做到這件事。如果現在做得到,而寫程式的方式維持不變——那我們什麼都沒失去,卻多拿到了一整套實踐。
這是一個把 AI 當作「品質預算」而不是「速度預算」的思考方式。 我覺得比大部分談 AI 生產力的內容都更值得參考。
Q:技術上怎麼串的?用 MCP 嗎?
沒有。就是在 Claude Code 提示字元打「我們來做個突變測試吧」。Claude Code 一開始問「要我幫你做一個工具嗎?」(Paul 笑說:我認識的工程師也都從這裡開始),他說不要,先去查有沒有現成的。Claude Code 上網找到 Stryker,安裝、設定、跑報告、迭代,全部自己來。
Q:那你怎麼知道測試是對的?它不就是在對著測試最佳化嗎?
這題問到了核心,Paul 的回答也是全場最好的一段:
我們有測試,我們也有「測試的測試」。
AI 對突變測試沒有任何控制權。突變測試是一個非 AI 的工具,純粹客觀——它看你的 codebase,找出每一個分支,在那裡注入 bug,然後跑你的測試。
從那種抽象的 AI 世界——它建模、它描述、它解釋——切換到這裡,有一種很清爽的感覺。這裡有個具體的東西,我可以把手放上去。 它幾乎像是找了一支獨立團隊來驗證。
但他也立刻補了但書:不會單靠它。在真正的醫療專案上,程式碼要 review、自動化測試要 review、測試步驟要 review。而且——
Code review 從來不是 100%,它大概是 80% 的檢查。突變測試給了我們額外的一個工具。
這場演講真正的貢獻
把三層疊起來看:
| 層 | 解決什麼 | 為什麼不夠 |
|---|---|---|
| 標準 | 給框架、給追溯性、可稽核 | 會變成打勾文化,拖慢創新 |
| BDD | 給透明度、給規格與程式碼的對齊 | 測試本身可能是 AI 幻想出來的 |
| 突變測試 | 給「測試值得信任」的客觀證據 | 慢、只能低頻跑、不能單獨依賴 |
三層有一個共同的邏輯:每一層都在為上一層提供它自己無法提供的獨立性。
而最深的一點是——當 AI 同時生成程式碼與測試,你需要在鏈條的某個地方,放進一個AI 無法說服、無法討好、無法繞過的東西。
突變測試之所以有效,不是因為它多聰明,恰恰是因為它夠笨。它不理解你的意圖,不在乎你想聽什麼,它只是機械地注入 bug,然後數你抓到幾隻。
在一個充滿了會說話、會解釋、會道歉、會保證自己做對了的工具的時代,「無法被說服的東西」本身就是一種稀缺資源。
值得補上的一句:這三層都沒有取代 Three Amigos。PRD 裡那個「六個月以下嬰兒」的缺口,最理想的攔截點不是突變測試,是一開始就有人問出那個問題。突變測試是最後一道網,不是第一道。
來源
Safe AI Coding in Regulated Domains: BDD, Mutation Testing & Medical Devices 講者:Paul Massie(Founder & Director, Bluefruit Software) https://www.youtube.com/watch?v=S9NZCDGnauI
延伸參考
- AAMI TIR45 — 醫療器材軟體開發使用敏捷實踐的指引(2012)
- IEC 62304 / IEC 82304 — 醫療器材軟體生命週期標準
- IEC 61508 — 功能安全;DO-178 — 航太軟體
- Stryker Mutator — 演講中使用的突變測試工具(JS/TS、C#、Scala)
- 其他語言的突變測試工具:PIT(Java)、mutmut / cosmic-ray(Python)、go-mutesting(Go)
發表迴響