TDD 工作流
用 Copilot 輔助 Red / Green / Refactor:先寫失敗測試,再做最小實現,最後重構並保持測試透過。
TDD(test-driven development,測試驅動開發)工作流的重點不是“讓 Copilot 多寫程式碼”,而是把 Copilot 限制在小步迴圈裡。先讓測試失敗(Red),再讓實現剛好透過(Green),最後只重構結構不改行為(Refactor)——三步缺一道,TDD 就退化成"AI 代寫程式碼 + 事後補測試"。
VS Code 官方 TDD 指南把 AI 輔助 TDD 拆成 Red、Green、Refactor 三個階段,並建議用自定義 agent、handoff 和自定義指令保持階段邊界。
1. 先給結論
Copilot 適合參與 TDD,但不能跳過 Red phase。最穩的做法是讓它一次只完成一個階段,並在階段切換前由開發者檢查測試、diff 和執行結果。
flowchart LR
Spec["需求 / 行為描述"] --> Red["Red: 寫失敗測試"]
Red --> CheckRed{"測試是否因目標行為失敗?"}
CheckRed -->|否| Red
CheckRed -->|是| Green["Green: 最小實現"]
Green --> CheckGreen{"測試是否透過?"}
CheckGreen -->|否| Green
CheckGreen -->|是| Refactor["Refactor: 清理結構"]
Refactor --> CheckRefactor{"全量相關測試仍透過?"}
CheckRefactor -->|否| Refactor
CheckRefactor -->|是| Next["下一條行為"]
style Red fill:#fee2e2,stroke:#dc2626,stroke-width:2px
style Green fill:#dcfce7,stroke:#16a34a,stroke-width:2px
style Refactor fill:#dbeafe,stroke:#2563eb,stroke-width:2px
2. 輸入要準備什麼
開始前把上下文壓到可驗證:
- 一條明確行為,而不是一整個模組。
- 現有測試框架和測試命令。
- 相關原始碼入口、介面約束和邊界條件。
- 專案測試風格,例如命名、fixture、mock、斷言偏好。
- 不允許改變的行為,例如相容性、效能、許可權和資料格式。
可以先在儲存庫裡寫一段團隊級測試指令,例如放在 repository instructions 或測試規範裡,告訴 Copilot 測試命名、mock 邊界和禁止行為。
3. Red phase:只寫失敗測試
在 Chat 或 agent 模式裡明確要求 Copilot 只寫測試,不寫實現:
写一个最小失败测试。
不要修改生产代码。
行为:
- 重复 email 返回 409。
- 响应体包含 code=EMAIL_EXISTS。
约束:
- 使用现有测试框架和 fixture。
- 只覆盖这个行为。
- 告诉我测试命令。人工檢查點:
- 測試是否驗證行為,而不是鎖死實現細節。
- 測試是否先失敗,並且失敗原因正是目標行為缺失。
- 是否沒有順手改生產程式碼。
- 邊界條件是否足夠,是否需要補錯誤路徑或許可權路徑。
如果測試沒有失敗,說明它沒有建立約束;如果失敗原因不對,先修測試,不進入 Green phase。
4. Green phase:只做最小實現
進入 Green phase 時,把失敗測試和錯誤輸出給 Copilot:
只修改实现。
让刚才这个失败测试通过。
要求:
- 不扩大功能范围。
- 不重写无关模块。
- 不新增抽象。
- 完成后运行相关测试。
- 说明改动点。人工檢查點:
- 實現是否只覆蓋當前測試約束。
- 是否引入了多餘配置、全域性狀態或異常分支。
- 是否破壞了相鄰測試。
- 是否能用一次 diff 解釋清楚。
Copilot 很容易在 Green phase 過度實現。看到“順手支援更多場景”的改動,先刪掉或要求它縮小範圍。
5. Refactor phase:只清理結構
Refactor phase 的輸入是“測試已透過的程式碼”。這一步不新增行為:
在测试通过的前提下,
检查这次实现是否需要重构。
只允许:
- 消除重复。
- 改善命名。
- 缩小函数职责。
- 移除临时变量或过度分支。
不允许:
- 新增功能。
- 改测试预期。
- 改外部 API。這一步的退出條件是相關測試仍然透過,且 diff 比實現階段更清晰。如果重構讓測試需要一起改,先判斷測試是否綁死實現;不能預設接受。
6. 常見失敗點
- 跳過 Red phase:Copilot 直接寫實現,再補測試,TDD 約束消失。
- 一次做太大:一個 prompt 覆蓋多個行為,失敗時無法定位原因。
- 測試實現細節:重構時測試跟著碎,說明斷言物件選錯。
- 只看綠色結果:測試透過不代表覆蓋了錯誤路徑、邊界值和許可權路徑。
- 無人工 handoff:一個 agent 連續寫測試、實現、重構,開發者只看最後結果。
深讀:什麼時候不適合 TDD + Copilot
需求還沒有行為邊界、現有程式碼沒有測試框架、介面仍在劇烈變化時,不要急著讓 Copilot 寫一堆測試。先把行為樣例、介面契約和測試命令定下來。
Copilot 可以幫你補測試,但不能替你決定產品行為。
本章自檢
- 是否每次只寫一個行為的失敗測試?
- 是否確認測試先因正確原因失敗?
- 是否只做讓當前測試透過的最小實現?
- 是否在重構後重新執行相關測試?
- 是否把成功 prompt 和失敗樣例沉澱進團隊 SOP?
透過標準:你能展示 Red 失敗輸出、Green 透過輸出、Refactor 後透過輸出,以及每一步的 diff。
官方來源
- Set up a test-driven development flow in VS Code —— VS Code 官方 TDD 指南。
- GitHub Copilot in VS Code —— VS Code 官方 Copilot 總覽。