「我知道 TDD 的三個步驟,但要怎麼讓 AI 真的照著做,而不是嘴巴上說『好的,我會遵循 TDD』,實際上還是一次把東西全寫完?」
這是這幾天讀者留言裡出現最多次的問題。過去六天,我們拆解了 Red 階段被跳過、Green 階段變成硬編碼、Refactor 階段夾帶沒有安全網的順手修改——三個問題其實有同一個根源:沒有東西強迫 AI 真的走完這三步,只是嘴上承認這三步存在。 今天要談的不是原則,是流程——怎麼設計一套具體的協作方式,讓「先紅、後綠、再重構」不只是知識,而是每次都會被執行的動作。
如果你只在 prompt 裡寫「請使用 TDD 的方式實作這個功能」,得到的結果,經常是 AI 在最終回覆裡宣稱自己遵循了 TDD,但實際產出的東西,跟一次到位完全沒有差別——測試檔案跟實作檔案幾乎同時出現,中間沒有一個「測試真的紅過」的痕跡。
這不是 AI 在說謊,是因為「TDD」這個詞對 AI 來說更像是一種風格標籤,而不是一組必須依序執行、且每一步都要交出證據的動作。跟人類工程師一樣,光是知道方法論存在,不足以保證每次都會確實執行——差別在於,人類工程師的紀律是靠反覆訓練跟自我要求累積的,AI 沒有這種累積,每次任務都要重新被逼一遍。
「遵循 TDD」是一個結果宣稱,不是一個可以驗證的動作——真正有用的流程設計,是把這個宣稱拆成三個各自要交出證據的檢查點。
具體做法是:不要把「用 TDD 實作 X」當成一個任務丟出去,而是拆成三個各自獨立、各自要求回報證據的階段。
第一階段:只寫測試,並且要求展示失敗
明確要求 AI 這一步只能寫測試程式碼,不能碰任何實作邏輯(如果對應的實作函式還不存在,就讓它保持不存在或回傳未實作的錯誤)。接著要求 AI 實際執行這個測試,並且把失敗訊息貼出來——不是「這個測試應該會失敗」這種推測性陳述,是真的跑過、真的看到紅字。
第二階段:只寫最小實作,並且要求展示通過
在確認測試真的紅過之後,才進入這一步,要求 AI 寫出能讓這個測試通過的最小實作,一樣要求執行測試並貼出通過的結果。這裡刻意強調「最小」,是為了避免 AI 把 Refactor 階段該做的事提前做掉,混淆了「能動」跟「寫得好」這兩件事。
第三階段:重構,並且要求逐步回報改動範圍
最後才進入重構,而且要求 AI 明確列出這次重構動了哪些檔案、哪些函式,跟第一階段的測試覆蓋範圍逐一對照——這正好呼應昨天談過的「重構範圍要跟測試覆蓋範圍對齊」。
用一組對照來看這個差異:
❌ 單一指令,沒有分階段檢查點:
「請用 TDD 的方式實作訂單折扣計算功能。」
→ AI 回傳一份測試檔案 + 一份實作檔案,
聲稱「已遵循 TDD 流程」,
但沒有任何環節真的驗證過測試曾經失敗過
✅ 分成三階段,各自要求交出證據:
「第一步:只寫測試,不要寫任何實作邏輯,
執行測試並把失敗訊息貼給我看。」
(確認測試真的紅了之後)
「第二步:寫出能讓這個測試通過的最小實作,
執行測試並把通過結果貼給我看。」
(確認測試真的綠了之後)
「第三步:現在可以重構,
列出這次重構動到的每一個檔案跟函式,
逐一標明各自有沒有測試覆蓋。」
→ 每個階段都有可以被檢查的具體產出,
不是一句「已完成」就結案
三個階段裡,第一階段的檢查點是最容易被忽略、卻最重要的。很多協作流程即使拆了階段,也只在最後檢查「有沒有寫測試」,跳過了「這個測試有沒有真的紅過」這一步——這正是 Day 06、Day 07 談過的問題在流程設計上的具體解法:紅燈證據不是選配步驟,是流程裡必須卡住、不能跳過的一關。
實務上,這代表你(或負責審查的人)在看到第一階段的產出時,要真的去確認貼出來的失敗訊息合理——是不是因為函式不存在、斷言不成立這類「正確原因」而失敗,而不是因為語法錯誤、環境設定錯了這種「錯誤原因」而失敗。一個因為打字錯誤而失敗的測試,跟一個因為邏輯正確地偵測到缺陷而失敗的測試,表面上都是紅字,意義完全不同。
老實說,這套分階段流程比「請用 TDD 實作」這種單一指令要花更多輪來回,對於真的很小、很有把握的改動,這種程度的儀式感可能不划算。這套流程該用在哪裡,取決於這段程式碼的重要性跟複雜度,不是每一次改動都值得走完整三階段——但只要你判斷這是一段需要 TDD 紀律的邏輯,這三個檢查點就不該被省略,因為省略掉的正是整個方法論真正發揮作用的地方。
回想你上一次要求 AI 用 TDD 方式開發的經驗:你有沒有真的看過那個測試失敗時的畫面,還是只看到最後測試通過的結果就直接採信了?
明天要談一個容易被忽略的細節:AI 寫的測試名稱看起來詳細、資訊量很大,但這些名稱實際傳達了什麼?測試命名本身,也是判斷一個測試有沒有價值的重要線索。