本文根據 GitHub 官方的 Copilot Chat Cookbook《Generating unit tests》、Cursor 官方教學《Reviewing and testing code》和 Claude Code 官方最佳實踐整理,資料核對於 2026-10-11。方法不限工具,換成 Trae、Cline、Codex 同樣適用。
適用於誰
- 知道該寫測試但一直沒時間寫的人;
- 搜「ai 寫單元測試」「ai 寫測試用例」的人;
- 讓 AI 寫過測試,結果要麼跑不起來、要麼全綠卻什麼都沒測到的人。
結論先說
- 寫測試是 AI 最划算的用法之一。Cursor 官方的說法:過去補齊測試很費力,多數團隊出了事才補;智能體讓寫測試變得容易得多——你讓它寫,再核對它寫得對不對。
- 測試也是你給 AI 的「驗證信號」。Claude Code 官方最佳實踐的第一條就是給它一個能自己運行的檢查;有了測試,它才能自己發現改壞了。
- 正確的順序是:先列場景 → 再寫 → 讓它自己跑 → 你核對斷言。直接說「給這個文件加測試」效果最差。
- 讓它照着項目裏已有的測試寫,框架、目錄、命名、mock 方式都跟現有的一致。
- AI 生成的測試要防一種失敗:為了通過而寫——斷言照抄了當前實現的行為,包括 bug。
五步流程
第一步:先讓它列要測什麼
不要一上來就要代碼。先讓它把場景列出來,你刪改確認:
text
先不要寫代碼。閱讀 src/services/pricing.ts 裏的 applyDiscount 函數,
列出應該測試的場景:正常情況、邊界值、非法輸入、和其他折扣疊加的情況。
每個場景一行,寫明輸入和期望結果。
Cursor 官方給的同類提示詞是「規劃一下怎麼給結帳流程做端到端覆蓋,應該測哪些場景?」和「現有測試沒覆蓋到這個功能的哪些邊界情況?」。這一步花的 token 很少,卻決定了測試的質素。
第二步:指定範圍和風格,讓它寫
Claude Code 官方對比過兩種寫法:「給 foo.py 加測試」是差的;「給 foo.py 寫一個測試,覆蓋用戶已登出的邊界情況,不要用 mock」是好的。把範圍、要覆蓋的情況、限制都說清:
text
按上面確認的場景,為 applyDiscount 寫單元測試。
- 參照 src/services/__tests__/cart.test.ts 的結構和命名方式
- 用項目已有的 vitest,不要引入新的測試庫
- 不要 mock 被測函數本身;只 mock 外部的網絡請求
- 每個測試只驗證一件事,測試名寫成「在……情況下應該……」
GitHub 官方的最小示例是在 Copilot Chat 裏選中函數後輸入:
text
/tests Generate unit tests for this function. Validate both success and failure, and include edge cases.
也就是「成功和失敗都要驗證,並包含邊界情況」。官方說明 Copilot 會先給出測試策略,再給出測試代碼;第一次使用時它可能會問你要不要為項目配置測試框架。
第三步:讓它自己運行並修到通過
在 Agent 模式下,把「運行」寫進指令:
text
寫完後運行這些測試。如果失敗,先判斷是測試寫錯了還是被測代碼有 bug:
測試寫錯了就改測試;如果你認為是代碼的 bug,停下來告訴我,不要改業務代碼。
最後一句很關鍵。不加的話,它可能為了讓測試變綠去改業務邏輯,或者反過來把斷言改成當前的錯誤行為。
第四步:你來核對斷言
這一步不能省。逐個看:
- 期望值是從需求來的,還是從代碼抄的? 比如需求是「滿 100 減 20」,測試裏卻斷言 99 元也減了 20——那是把 bug 固化成了測試。
- 有沒有真的斷言? 只調用函數、不檢查結果的測試永遠通過。
- 是不是 mock 得太多? 把被測邏輯本身都 mock 掉,測的就只是 mock。
- 邊界值在不在? 0、負數、空字符串、空數組、最大值、剛好等於閾值的那個數。
一個快速驗證辦法:故意把業務代碼改錯一處(比如把 > 改成 >=),重新跑測試。如果測試仍然全綠,說明這組測試沒有測到這個邏輯。驗證完記得改回來。
第五步:修 bug 時先寫一個失敗的測試
Claude Code 官方的示例提示詞裏有這樣的要求:先寫一個能復現問題的失敗測試,再修。Cursor 官方也把「為我們修掉的那個 bug 寫回歸測試」列為好提示詞。
text
用戶反饋:優惠碼大小寫不同時會被當成兩個碼重複使用。
先寫一個能復現這個問題的失敗測試,運行確認它確實失敗;
然後修復代碼,再運行確認測試通過,並且其他測試沒有被影響。
好處有兩個:證明你確實復現了問題;以後有人改回去,測試會攔住。
不同類型的測試怎麼要
| 類型 | 提示詞要點 | 官方出處 |
|---|---|---|
| 單元測試 | 指定函數、成功 + 失敗 + 邊界、照已有測試的寫法 | GitHub Cookbook |
| Mock 對象 | 說明要隔離哪個外部依賴(網絡、數據庫、時間) | GitHub Cookbook 有《Create mock objects》 |
| 集成測試 | 指定接口和已有的測試基礎設施目錄 | Cursor 示例:用 src/__tests__/ 裏已有的測試設施給支付 API 搭集成測試 |
| 端到端測試 | 描述用戶流程;項目沒配 Playwright 時可以讓它從頭搭 | Cursor:智能體可以搭好項目、寫配置、建第一個測試 |
| 介面手動驗證 | 讓智能體用瀏覽器工具點一遍並截圖 | Cursor:智能體可以通過瀏覽器檢查介面狀態和流程 |
8 條可複製的提示詞
列出這個函數現有測試沒有覆蓋的分支,按風險排序。為這個函數寫單元測試,成功、失敗、邊界值都要有;照 tests/ 目錄裏已有測試的風格。這個模組依賴系統時間和網絡,寫測試時只隔離這兩樣,其餘用真實實現。運行全部測試,把失敗的列成表:測試名、失敗原因、你判斷是測試問題還是代碼問題。為剛修的這個 bug 補一個迴歸測試,測試名裏寫清復現條件。這個測試偶爾失敗。找出不穩定的原因(時間、順序、共享狀態),先解釋再改。檢查這些測試裏有沒有「沒有斷言」或「斷言永遠為真」的用例。為這個接口寫集成測試:正常返回、參數缺失、無權限、資源不存在四種情況。
常見問題
Q:測試全綠,但我不放心?
用上面的「故意改錯」辦法抽查幾處。也可以讓另一個全新會話來審這些測試——寫測試的那個對話容易認為自己寫得對。
Q:AI 寫的測試跑不起來?
多半是它沒看項目的測試配置就動手了。讓它先讀 package.json / pyproject.toml 和一個已有的測試文件,或者把運行測試的命令寫進 AGENTS.md,見《AGENTS.md 怎麼寫》。AGENTS.md 官網的說明是:寫在裏面的測試命令,智能體會自動去跑。
Q:覆蓋率要追到多少?
官方文檔沒有給數字。比數字更有用的是:核心業務邏輯、算錢的地方、權限判斷、出過 bug 的地方都有測試。
Q:能讓它每次改完自動跑測試嗎?
可以用 hooks:Kiro、Claude Code、Cursor 都支持在智能體儲存文件後自動執行命令。見《Claude Code Hooks 怎麼用》和《Kiro Spec 模式怎麼用》。
Q:測試跑得很慢怎麼辦?
Cursor 官方專門講過:智能體越多,瓶頸越在最慢的環節。測試要 10 分鐘、並行 10 個智能體,就是近兩小時的等待;把測試提速一半,每一輪都省時間。
Q:有現成的測試類提示詞嗎?
本站提示詞庫的編程開發分類裏有測試相關的模板,可以按語言改。
參考資料
- Generating unit tests(GitHub 官方 Copilot Chat Cookbook):https://docs.github.com/en/copilot/tutorials/copilot-cookbook/testing-code/generate-unit-tests
- Reviewing and testing code(Cursor 官方教學):https://cursor.com/learn/reviewing-testing
- Best practices(Claude Code 官方):https://code.claude.com/docs/en/best-practices
0 條評論
還沒有評論,來搶沙發~