一分鐘重點:把函式貼給 AI 叫它寫測試,三秒就能拿到一大段看起來很專業的 test code,但九成的人拿到的是「只測正常路徑、斷言又空泛」的假安全感。真正會用 AI 寫測試的人,順序是反過來的:先逼 AI 把正常、邊界、例外三類輸入「列成清單」,自己審過、補上業務規則,再讓它寫程式碼,最後一條一條審斷言。這篇給你完整流程、可複製 Prompt,以及怎麼看穿 AI 產的爛測試。
單元測試是少數「AI 幫得上大忙、但你不審就會反咬一口」的任務。寫對了,補測試的時間從一個下午縮到半小時;用錯了,你會得到一整套永遠綠燈、卻什麼 bug 都抓不到的測試,反而讓整個團隊更敢亂改程式碼。差別不在模型多強,在你怎麼指揮它。
為什麼直接叫 AI「幫這個函式寫測試」會出事
先看最常見的用法。你把一個函式貼進去,打一句「幫我寫單元測試」,AI 唰一下給你五六個 test case,全綠,覆蓋率還 92%。看起來很美好,問題藏在三個地方。
第一,它幾乎只測 happy path。給合法輸入、回傳合理結果,這種案例 AI 寫起來最順,因為從函式簽章就猜得到。但 bug 很少躲在正常路徑,都躲在「空陣列」「數量是 0」「日期跨年」「金額剛好等於門檻」這些邊界,還有「傳進來是 null」「外部 API 掛掉」這些例外。AI 不會主動幫你想這些,除非你逼它。
第二,斷言空泛。你會常看到 expect(result).toBeTruthy()、expect(result).toBeDefined()、assert result is not None。這種斷言的意思是「有東西回來就算過」,等於沒測。一個算錯金額的函式只要它有回傳數字,這種斷言照樣綠燈。
第三,也是最危險的:測試跟著實作一起錯。AI 寫補測試時,是「讀你的程式碼、反推它應該回傳什麼」。如果你的函式本來就有 bug,算出來是錯的,AI 會把這個錯誤的輸出當成「正確答案」寫進 expect(...).toBe(錯誤值)。結果就是——測試永遠通過,bug 永遠在,而且你還因為「有測試」而更放心。這是用 AI 補測試最容易踩、又最難自己發現的坑。
理解這三件事,後面的流程就是針對它們設計的。
正確流程:先列案例清單,再寫測試
老手請 AI 寫測試,會刻意拆成兩個回合,中間插一個「人」。
第一回合,只要清單,不要程式碼。 把函式貼上去,要求 AI 先用條列方式列出它打算測哪些輸入,分成「正常 / 邊界 / 例外」三類,每一條寫清楚「輸入是什麼、預期結果是什麼、為什麼要測」。這一步只產生一張表,不產生任何 test code。
為什麼要這樣?因為清單是「人類最容易審」的形式。你掃過去馬上看得出來:喔,它沒測空陣列、沒測負數、沒考慮到我們業務規定「未滿 18 歲要擋下來」。這時候你直接在清單上補:「加上 age 剛好 18、剛好 17 的案例」「補上 list 為空時應該回傳 0 而不是報錯」。把業務規則灌進去——這正是 AI 最不懂、最需要你的地方。
第二回合,才讓它把確認過的清單寫成測試程式碼。 這時候 AI 是照著你審核過的規格寫,而不是照著可能有 bug 的實作猜,測試的品質直接差一個檔次。
這個「先清單後程式碼」的動作,就是在把人塞進 AI 的決策鏈裡。多花三分鐘審清單,省下的是事後 debug 一整套假測試的時間。
可複製 Prompt 範本
下面這份範本就是上面流程的具體化。把你的函式貼進去,照著用:
你是一位資深測試工程師,擅長寫嚴謹的單元測試。
【任務】
我會貼一個函式,請你協助我寫單元測試。
但「先不要寫程式碼」,分兩階段進行。
【第一階段:列測試案例清單】
請先用表格列出你打算測的所有案例,分成三類:
1. 正常路徑(typical inputs)
2. 邊界條件(空值、0、空字串、空陣列、最大/最小、剛好等於臨界值、邊界±1)
3. 例外情況(null/undefined、型別錯誤、超出範圍、重複、外部依賴失敗或丟錯)
每一列請寫清楚:輸入 / 預期結果 / 這條在驗什麼。
重點:預期結果請依「需求規格與常理」推導,
不要只是照我貼的實作反推——如果你覺得實作的行為可能有問題,請標記出來提醒我。
【第二階段:等我確認清單後,再寫測試程式碼】
- 測試框架:<填 Jest / Vitest / pytest / JUnit…>
- 每條測試要有清楚的測試名稱,說明在驗什麼情境。
- 斷言要驗到「具體的值、長度、欄位內容或丟出的錯誤型別」,
禁止使用 toBeTruthy / toBeDefined / 只判斷有無回傳這類空泛斷言。
- 例外案例要用框架的方式驗證有正確丟錯(例如 expect(...).toThrow)。
【我的函式】
<把完整函式、它依賴的型別/常數、以及它在系統裡負責什麼,一起貼在這>
先做第一階段,把案例清單給我,我審完會回覆你補充的業務規則。
關鍵在三件事:強迫分兩階段、明文要求三類案例、明文禁止空泛斷言。把這三條寫死在 Prompt 裡,你會發現 AI 產出的測試品質穩定很多,不用每次靠運氣。
一段實際的對照
假設你有一個算運費的函式(簡化版):
// 訂單金額滿 1000 免運,否則運費 80;金額需為正數
function shippingFee(amount) {
if (amount >= 1000) return 0;
return 80;
}
新手 Prompt 拿到的測試通常長這樣:
test('計算運費', () => {
expect(shippingFee(1200)).toBeTruthy(); // 1200 回傳 0,0 是 falsy,這條其實會掛
expect(shippingFee(500)).toBe(80);
});
只測了兩個正常值,斷言還寫錯(0 是 falsy)。而走「先列清單」流程,你會被提醒到這些案例:amount 剛好等於 1000(臨界值,該免運)、999(差一塊,要收 80)、0、負數、傳進字串或 null。補完之後:
test('滿 1000 免運', () => expect(shippingFee(1000)).toBe(0));
test('999 仍需運費', () => expect(shippingFee(999)).toBe(80));
test('金額為 0 收運費', () => expect(shippingFee(0)).toBe(80));
test('負數金額應拋錯', () => expect(() => shippingFee(-50)).toThrow());
寫到第四條你會發現——原函式根本沒處理負數!測試逼出了實作的漏洞。這就是好測試的價值:它不是替現狀背書,而是替「正確的行為」設防線。順帶一提,這也示範了為什麼「照實作反推」很危險:如果你只叫 AI 看實作寫測試,它根本不會質疑負數,因為原函式沒擋,它就以為負數回 80 是對的。
台灣團隊實戰:一句「先列清單」救回的信心
台中一家做 SaaS 出貨管理的新創 Shipfast,後端團隊四個人,主力是工程師林冠廷。他們的計費模組累積了兩年,沒幾條測試,每次改報價邏輯都像拆地雷,改完只能手動點一輪,沒人敢大改。
第一次他們試著用 AI 補測試,是直接把整個 billing.js 丟給 Cursor,叫它「補完整測試」。產出兩百多行、覆蓋率衝到 88%,看起來很安心。直到一週後一個客戶反映「滿額折扣沒生效」,他們回頭一看——那條折扣邏輯本來就寫錯了,而 AI 補的測試是照著錯的實作寫的,expect 裡填的正是錯誤金額,所以一路全綠,沒人發現。
林冠廷後來改了做法。他不再讓 AI 一口氣寫,而是改用「先列清單」的兩階段流程,並且在 Prompt 裡加一句關鍵指令:「預期金額請依我們的計費規格推導,不要照現有程式碼反推,覺得實作可疑就標記。」第二次跑下來,AI 在清單階段就標了三個「這裡的行為跟一般折扣邏輯不一致,請確認」,其中兩個正是真 bug。重要的金額案例,他要求團隊自己用計算機對一遍答案,再寫進斷言。
三週後的結果:計費模組從 9 條測試補到 140 多條,更重要的是抓出 4 個潛藏 bug。林冠廷的說法是:「以前覆蓋率數字好看但心裡沒底,現在條數沒灌水、每條斷言都對過答案,改報價邏輯終於敢一次改一大塊。」他們現在團隊規範寫死一條:AI 產的測試,清單一定要人審、關鍵斷言一定要手算對答案,才能 merge。
怎麼審查 AI 產的測試品質
測試寫出來只是一半,會審才是真功夫。逐條過這份檢查清單:
- 斷言有沒有驗到具體值? 看到
toBeTruthy、toBeDefined、not None、assertTrue(result)這類就退回,要求改成驗具體數值、長度、欄位或錯誤型別。 - 預期值是怎麼來的? 心裡問一句:這個
expect(...).toBe(X)的 X,是 AI 照規格算的,還是照實作抄的?關鍵案例自己手算一遍對答案,這是防「測試跟著實作錯」唯一可靠的辦法。 - 三類案例齊不齊? 把測試攤開,數一數有沒有邊界(空、0、臨界±1)、有沒有例外(null、丟錯、依賴失敗)。只有正常路徑就是沒做完。
- 每條測試是不是只測一件事? 一個 test 裡塞十個
expect、驗一堆不相關的東西,壞了很難定位。請 AI 拆細。 - 測試名稱看不看得懂? 好名稱像「金額剛好 1000 應免運」,壞名稱像「test case 3」。名稱爛通常代表寫的人(或 AI)自己也沒想清楚在驗什麼。
- 故意改壞實作,測試會不會紅? 最硬的驗收法:把被測函式偷偷改錯一個地方(mutation),跑測試。如果還是全綠,代表這套測試根本沒在防守,是裝飾品。
這份清單花不了五分鐘,但它是 AI 產測試「能不能信」的分水嶺。
常見錯誤與 AI 的限制
把容易踩的雷集中講一次:
測試跟著實作一起錯——前面講過,最隱蔽。解法是叫 AI 依規格推導、自己手算關鍵答案、用 mutation 驗收。
只測 happy path——AI 的預設傾向。解法是 Prompt 裡強制三類案例、先審清單再寫。
斷言空泛——衝覆蓋率最容易產生的副作用。解法是明文禁用空泛斷言、審查時逐條看。
過度信任覆蓋率數字——覆蓋率只說「這行有被跑到」,不說「行為有被驗對」。空泛斷言可以讓覆蓋率很漂亮卻零防護力。把覆蓋率當「哪裡完全沒碰到」的地圖就好,別當品質指標。
至於 AI 本身的限制,要認清三點。其一,AI 不懂你的業務規則。「未滿 18 不能下單」「VIP 免運門檻是 500 不是 1000」「跨年訂單算前一年業績」——這些它無從得知,只能靠你在清單階段補。其二,AI 不知道你系統的真實依賴行為,它對外部 API、資料庫、時間的 mock 常常想當然耳,要你校正。其三,AI 產的測試一定要人工審,它是把你從「從零寫一百條」加速到「審一百條、修二十條」,不是讓你從此不用看。把它當一個手很快但不懂你產品的實習生用,剛剛好。
結語:今天就挑一個函式試一次
不用大張旗鼓導入。打開你專案裡那個「最沒人敢動、又沒測試」的函式,把上面的可複製 Prompt 套上去,走一次兩階段流程:先看 AI 列的案例清單、補上你的業務規則、再讓它寫程式碼、最後逐條審斷言、故意改壞跑一次看會不會紅。一個函式做完,你就會抓到手感,知道哪些該補、哪些 AI 在唬你。
把這個流程變成團隊規範:AI 產的測試,清單要人審、關鍵斷言要對答案、要能擋住 mutation 才准 merge。這樣補出來的測試才是真的防線,而不是讓大家更敢亂改的假安全感。現在就挑一個函式,開始第一回合。
本文由 AgentAI 智庫(agentai.tw) 整理撰寫,台灣最大的繁體中文 AI 知識站。
常見問題 FAQ
把函式貼給 AI,它就能寫出好的單元測試嗎?
為什麼 AI 產的測試常常跟著實作一起錯?
怎麼讓 AI 不要只測 happy path?
AI 寫的斷言太空泛怎麼辦?
需要先寫好測試再請 AI,還是先有實作再補測試?
覆蓋率 100% 是不是就代表測試夠好?
延伸閱讀
每週把這類實戰教學寄給你
訂閱 AgentAI 智庫情報週報,新的 Prompt、AI Skills、工作流與教學第一時間收到。
免費 · 隨時取消