iT邦幫忙

2026 iThome 鐵人賽

DAY 16
0
Software Development

AI 時代的 TDD:讓 AI 寫 Code,但不要讓它決定品質系列 第 16 篇

Day 16:測試品質的判斷標準——AI 可以幫你寫,但誰來判斷這個測試值不值得留?

  • 分享至 

  • xImage
  •  

前言:測試都在,為什麼還要問「值不值得留」?

「這個檔案裡已經有 40 個測試案例了,還要花時間逐條審查嗎?」

如果你也這樣想過,先想一件事:這 40 個測試案例裡,有幾個是空斷言(Day 05)、幾個把待測物件本身 mock 掉了(Day 13、14)、幾個名稱看起來詳細但其實只是複述實作細節(Day 12)、幾個只驗證了 happy path(Day 15)?測試數量從來不是品質的證據,一份看起來完整的測試檔案,很可能大部分內容都經不起檢驗。

這個系列第二部走到今天,已經拆解過好幾種 AI 常犯的測試錯誤。今天要做的是把這些散落的判斷準則收斂成一套具體的檢查清單,用來回答一個更根本的問題:這個測試,值不值得留在程式碼庫裡?

今日目標

  • 理解「測試存在」跟「測試值得留下」是兩個不同層次的問題
  • 把前面幾天講過的判斷準則收斂成一份可以逐條檢查的清單
  • 學會用一個具體的思考順序,快速判斷一個測試該留、該改、還是該刪
  • 建立「審查測試」跟「審查程式碼」該用不同標準這個認知

為什麼「留著」本身也有成本

第一部(Day 1-7)建立的核心認知,是 TDD 的 Red-Green-Refactor 循環每一步都在驗證某件具體的事——測試能不能真的偵測到問題(Red)、實作是不是真的符合規則意圖(Green)、重構後行為有沒有維持一致(Refactor)。一個沒有通過這些驗證的測試,不只是「沒有幫助」,它還有實際成本:

它會在別人改動相關程式碼時,製造一種「這裡有測試保護」的錯覺;它會在重構時被要求跟著改,卻沒人記得它原本在驗證什麼;它會拖慢測試套件的執行時間,卻沒有換來對應的信心。一個假陽性測試不是零貢獻,是負貢獻——它消耗維護成本,卻不提供保護力,還會讓團隊誤判自己的測試涵蓋率。

收斂成一份檢查清單

把前面幾天的判斷準則收斂起來,一個測試該不該留,可以照這個順序檢查:

✅ 五步驟檢查清單:

1. 這個測試有沒有真的紅過?(Day 06、07)
   → 故意讓實作退回錯誤版本,這個測試會不會抓到?
   → 抓不到 = 假陽性,不算數

2. 斷言驗證的是業務結果,還是實作細節?(Day 04、05、12)
   → 斷言「回傳值不是 null」還是「回傳值等於 250」?
   → 只驗證存在性/型別 = 弱斷言,該加強或刪除

3. Mock 的對象是外部依賴,還是待測邏輯本身?(Day 13、14)
   → Mock 掉付款閘道合理,Mock 掉待測函式的核心運算邏輯不合理
   → 待測邏輯被 mock 掉 = 測試在驗證 mock 設定,不是驗證程式碼

4. 測試名稱能不能讓人不看程式碼就知道在驗證什麼?(Day 12)
   → 名稱只複述方法簽章 = 沒有傳達情境跟預期行為

5. 這個情境是 happy path,還是邊界/例外案例?(Day 15)
   → 一個函式如果只有 happy path 測試,涵蓋率再高也不算完整

用一組對照具體看這份清單怎麼運作:

❌ 沒有檢查清單,只看「有沒有測試」:
「這個 PaymentService::charge() 方法有 5 個測試案例,
 涵蓋率 90%,應該沒問題。」
→ 沒人知道這 5 個案例裡,有幾個是真的驗證了扣款邏輯,
  有幾個只是驗證「回傳值不是 null」

✅ 套用五步驟檢查清單逐一審查:
「這 5 個案例裡:2 個斷言了具體扣款金額(通過第 2 步)、
 1 個把付款閘道跟待測的折扣計算邏輯一起 mock 掉了
 (沒通過第 3 步,待測邏輯被連帶隔離)、
 2 個只測了正常金額,沒有 0 元或負數的案例
(沒通過第 5 步)。實際上只有 2 個案例真正可信。」
→ 涵蓋率數字背後的真實品質被攤開來檢查,
  而不是被一個總覽數字掩蓋

這份清單的價值不在於它多完整,而在於它把「這個測試好不好」從一個模糊的直覺判斷,變成一連串具體、可以逐條回答的問題——這正是這個系列從 Day 01 開始反覆強調的:把判斷收斂成可以被檢驗的具體標準,而不是依賴籠統的信任。

審查測試跟審查程式碼,標準不一樣

有一個容易被忽略的地方:審查測試程式碼時,人很容易套用審查一般程式碼的直覺——這段邏輯清不清楚、有沒有重複、命名好不好——卻漏掉測試專屬的那些問題(會不會真的失敗、有沒有測到業務結果)。 測試程式碼即使寫得再乾淨、再符合一般的程式碼風格規範,如果沒通過上面五步驟裡的第 1、2、3 步,它作為一個「測試」仍然是不合格的。

反過來說,一個測試的程式碼風格不夠優雅(例如重複的 setup 邏輯沒有抽出來),但只要它真的驗證了正確的行為,價值遠高於一個風格完美卻是假陽性的測試。審查測試時,「這個測試有沒有效力」永遠該排在「這段程式碼寫得漂不漂亮」前面。

今日思考題

挑一個你手上現有的測試檔案,隨機選 3 個測試案例,用今天這份五步驟清單逐一檢查。有幾個案例能通過全部五步?如果比例低於你的預期,那份測試檔案的實際涵蓋率,可能遠低於報告上顯示的數字。

今日重點回顧

  • 測試數量不是品質的證據,一個假陽性測試是負貢獻,不是零貢獻
  • 五步驟檢查清單:有沒有真的紅過、斷言驗證的是結果還是細節、Mock 的是外部依賴還是待測邏輯本身、名稱能不能傳達情境、有沒有涵蓋邊界案例
  • 審查測試要優先看「有沒有效力」,其次才是程式碼風格好不好
  • 把「這個測試好不好」的判斷收斂成可逐條檢查的具體問題,而不是依賴籠統的信任

第二部(Day 8-16)到這裡告一段落——從「Green 階段的最小手段」、「硬編碼案例」、「Refactor 階段的順手重構」、「流程設計」、「命名陷阱」、「Mock 濫用」、「過度 mock 案例」,一路到今天的「邊界情境」跟「品質判斷清單」,講的都是同一件事的不同切面:AI 產出測試程式碼的速度,遠遠超過人審查的直覺速度,所以判斷標準必須從直覺變成可以被檢驗的具體清單。

明日預告

明天進入第三部:「讓 AI 遵守 TDD 循環的具體做法」,第一篇要拆一個容易被誤解的指標——Coverage 不是品質,AI 很容易把「覆蓋率高」直接當成「品質好」的證據,這中間的落差比想像中大。


上一篇
Day 15:邊界情境——AI 容易只測 happy path,例外情境要人主動要求
下一篇
Day 17:Coverage 不是品質——AI 很容易把「覆蓋率高」當成「品質好」的證據
系列文
AI 時代的 TDD:讓 AI 寫 Code,但不要讓它決定品質 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言