AI 寫的 Test 怎麼信任
「Claude 幫我生了 30 個 test、全綠、可以合了吧?」這是 QA 最該警覺的一句話。AI 生測試最大的風險不是它寫不出來、是它寫出一堆綠燈但根本沒測到東西的假測試、給你虛假的安全感。這篇給你一套信任邊界 + review SOP。
核心問題:綠 ≠ 有測到
flowchart LR
A[AI 生 30 個 test] --> B[全部綠燈 ✅]
B --> C{綠燈代表什麼?}
C --> D["只代表:沒拋錯"]
C -.以為.-> E["以為:有測到 bug"]
D --> F[改壞 code<br>test 還是綠 ❌]
style B fill:#10b981,color:#fff
style E fill:#ef4444,color:#fff
style F fill:#ef4444,color:#fff
傳統人寫 test、至少寫的時候腦中有「我要抓什麼」。AI 生 test 是從語法層補出一個看起來合理的 test、不保證背後有測試意圖。綠燈只證明「程式沒爆」、不證明「斷言有意義」。
7 種「綠燈但沒用」的假測試
mindmap
root((AI 假測試))
恆真斷言
assert true
expect 1 == 1
過度 mock
mock 掉被測對象本身
測到的是 mock 不是 code
驗呼叫不驗結果
只 assert 函式被呼叫
沒驗回傳值對不對
幻覺預期值
AI 自己編的 expected
沒對規格
只測 happy path
0 個邊界
0 個異常
快照記錯誤
snapshot 記下當前 bug
把錯的當基準
重複洗數量
10 個 case 測同一條路
覆蓋假象
| # | 假測試 | 怎麼看出來 |
|---|---|---|
| 1 | 恆真斷言 | expect(result).toBeDefined() 永遠過、沒驗內容 |
| 2 | 過度 mock | 連被測 function 都 mock 掉、測的是假貨 |
| 3 | 驗呼叫不驗結果 | 只 toHaveBeenCalled()、沒比對回傳值 |
| 4 | 幻覺預期值 | expected 是 AI 算的、不是規格給的 |
| 5 | 只有 happy path | 0 邊界、0 異常、0 安全 |
| 6 | 快照記錯誤 | snapshot 把當前(含 bug)行為當基準 |
| 7 | 重複洗數量 | 10 個 case 其實測同一條路徑 |
信任分級 — 哪些能交給 AI
flowchart TB
subgraph Green["🟢 可放心交給 AI"]
G1[Boilerplate / setup]
G2[明確規格的 happy path]
G3[重複結構的 case]
G4[測試命名 / 註解]
end
subgraph Yellow["🟡 AI 出草稿 + 人工把關"]
Y1[邊界 / 異常覆蓋]
Y2[斷言的預期值]
Y3[mock 邊界該畫在哪]
end
subgraph Red["🔴 不可全交給 AI"]
R1[Domain 規則 預期值]
R2[安全相關斷言]
R3[覆蓋是否足夠的判斷]
end
style Green fill:#10b981,color:#fff
style Yellow fill:#f59e0b,color:#fff
style Red fill:#ef4444,color:#fff
一句話:AI 可以幫你「打字」、不能幫你「決定預期值對不對」跟「覆蓋夠不夠」。預期值與覆蓋判斷、是 QA 不外包的核心。
5 步 Review SOP
flowchart LR
S1["1、改壞測試<br>mutation 抽查"] --> S2["2、查斷言<br>驗結果非呼叫"]
S2 --> S3["3、查預期值<br>對規格不對 AI"]
S3 --> S4["4、查覆蓋<br>邊界/異常/安全"]
S4 --> S5["5、查 mock<br>沒 mock 掉被測對象"]
style S1 fill:#a855f7,color:#fff
style S3 fill:#a855f7,color:#fff
style S5 fill:#a855f7,color:#fff
Step 1 — 改壞 code,看 test 會不會紅
最快的真假測試判別法。故意把被測邏輯改錯一行:
# 被測 code(故意改壞)
def calc_overtime(hours):
# return hours * 1.33 # 原本對的
return hours * 1.0 # 故意改錯
# 如果 AI 生的 test 還是綠 → 這 test 是假的
合併前對關鍵模組做這件事、或直接上 mutation testing 工具自動跑(見下)。
Step 2 — 斷言驗「結果」不是驗「呼叫」
// ❌ AI 常生這種:只驗有被叫
expect(saveUser).toHaveBeenCalled();
// ✅ 要的是驗結果對不對
expect(result.status).toBe('active');
expect(result.email).toBe('[email protected]');
Step 3 — 預期值必須來自規格、不是 AI 腦補
這是最隱蔽的雷。AI 會「算」一個預期值填進去、看起來合理但跟業務規則不符。
Prompt 改法:
「產生 test、但 expected 值欄位先留 TODO、
並在旁邊註明這個值該依據哪條規格決定。
不要自己猜數字。」
預期值你親自對規格填、或 review 時逐一對。金融 / 稅務 / 健保類的數字、100% 人工核對。
Step 4 — 覆蓋盤點
要求 AI 自己列覆蓋矩陣、你檢查缺口:
Prompt:
「用表格列出你產的 test 覆蓋哪些情境:
happy / 邊界 / 異常 / 安全 / 併發。
哪些情境『沒』被覆蓋?老實列出來。」
AI 常只給 happy path。缺的邊界 / 異常自己補。
Step 5 — 檢查 mock 邊界
// ❌ 把被測對象本身 mock 掉 → 測了個寂寞
jest.mock('./userService'); // 然後又在測 userService
// ✅ 只 mock 外部邊界(DB / API / 時間)
jest.mock('./db');
原則:只 mock external boundary、不 mock 被測主體。
用 Mutation Testing 反向驗證
Review 靠肉眼會累、用 mutation testing 自動驗「測試真的會抓 bug」:
# JS/TS
npx stryker run
# Python
mutmut run
# Java
mvn org.pitest:pitest-maven:mutationCoverage
flowchart LR
M[Mutation Tool] --> C[自動改壞 code 100 處]
C --> T[每改一處跑一次 test]
T --> R{test 有紅嗎?}
R -->|紅| K["killed ✅ 好測試"]
R -->|綠| S["survived ❌ 假測試"]
style K fill:#10b981,color:#fff
style S fill:#ef4444,color:#fff
Mutation score 比 coverage 誠實。Line coverage 90% 但 mutation score 30%、代表 test 跑過了 code 卻抓不到 bug — 正是 AI 假測試的典型特徵。CI 設 mutation score 門檻、AI 假測試直接被擋。
CI 守門設定
# AI 生的 test 進 CI 前的守門
gates:
- 改壞抽查(關鍵模組 mutation testing)
- 禁恆真斷言(lint 規則 no-tautology)
- 覆蓋矩陣需附在 PR description
- 預期值需標規格來源
- 禁 mock 被測主體(review checklist)
反模式
flowchart TD
Anti[AI 測試反模式] --> A1["全綠就合、不抽查"]
Anti --> A2["相信 AI 算的預期值"]
Anti --> A3["只看 coverage %、不看 mutation"]
Anti --> A4["AI 生多少 case 就交多少"]
Anti --> A5["mock 到測不到真實邏輯"]
Anti --> A6["snapshot 全收、含 bug 一起記"]
style A1 fill:#ef4444,color:#fff
style A2 fill:#ef4444,color:#fff
style A3 fill:#ef4444,color:#fff
style A4 fill:#ef4444,color:#fff
style A5 fill:#ef4444,color:#fff
style A6 fill:#ef4444,color:#fff
給 QA 的 5 句
- 綠燈只代表沒爆、不代表有測到
- 改壞 code 不紅的 test 是假的
- 預期值對規格、不對 AI
- Mutation score 比 coverage 誠實
- AI 幫打字、覆蓋判斷你自己扛
最後
AI 生 test 能省一半打字時間、但省不掉 QA 的判斷。把這套 review SOP 變成 PR checklist、再加一道 mutation testing 守門、你就能放心讓 AI 加速、又不會被假測試騙。信任不是「相信 AI」、是「建立可驗證的信任流程」。
延伸: - AI 生成 Code 怎麼測 - 用 LLM 生 Test Case - QA 的 AI Workflow Daily Routine - Self-healing Tests with LLM