跳至正文
我的好朋友 Claude
第 111 期|Claude Code|創作者、打工仔|

同 Claude Code 做 TDD:先講清楚行為,再由測試帶住實作

用一個顯示名稱函數示範紅、綠、重構。學識分辨測試真正失敗嘅原因,避免程式同測試一齊迎合錯誤假設。

難度 ★★★時間 50 分鐘用具 Claude Code、已設定測試框架嘅練習專案
【編者撰】一個香港人

先講清楚規則,再寫測試

Claude 寫完程式,再照住自己嘅實作寫測試,可能兩邊都認同同一個錯誤。TDD 將次序調轉:先用例子定義想要嘅行為,確認測試能夠捉到缺失,再補實作。

唔一定要你親手打晒所有測試。Claude 可以草擬,但規則同預期結果要有人獨立判斷。尤其金額、日期、權限等規則,唔好由現有程式反推成唯一答案。

1. 用一個細例子定義要求

假設網站要顯示一個已提供嘅名稱,規則係:去除頭尾空白;空字串或者全部空白時顯示「未提供」;保留名稱中間嘅空格。呢度只接受字串,唔順便設計其他資料型別。

以下用 Vitest 示範。請放喺已經設定好 TypeScript 同 Vitest 嘅練習專案,唔好為咗抄範例而改動正式專案嘅測試框架。

import { expect, test } from 'vitest'
import { formatDisplayName } from './format-display-name'

test('去除名稱頭尾空白', () => {
  expect(formatDisplayName('  Chan Tai Man  ')).toBe('Chan Tai Man')
})

第一輪可以先建立只會拋錯嘅函數,令匯入同編譯都成立:

export function formatDisplayName(value: string): string {
  throw new Error('尚未實作')
}

執行專案既有嘅測試命令,確認失敗原因係函數未實作。如果只係找不到套件、匯入路徑錯誤或者測試根本冇被發現,呢次「紅燈」仲未證明測試有效。

2. 一次通過一項要求

◉ 第一輪實作

已確認「去除名稱頭尾空白」測試因為函數未實作而失敗。

請只修改 format-display-name.ts,用最直接做法滿足呢項要求,再執行對應測試。唔好修改測試預期值,唔好加入未提出嘅名稱格式規則。回報實際命令同結果。

有咗第一輪綠燈,再加入空白輸入:

test('冇名稱時顯示後備文字', () => {
  expect(formatDisplayName('')).toBe('未提供')
  expect(formatDisplayName('   ')).toBe('未提供')
})

test('保留名稱中間嘅空格', () => {
  expect(formatDisplayName('Chan  Tai Man')).toBe('Chan  Tai Man')
})

新增測試應該能揭示仲未處理嘅規則。完成後,一個合理實作係:

export function formatDisplayName(value: string): string {
  const trimmed = value.trim()
  return trimmed === '' ? '未提供' : trimmed
}

呢個例子重點係逐項確認行為,唔係追求多輪對話。規則已經清楚嘅細函數,可以一次整理相關例子,再逐步完成。

3. 重構時保留同一套驗收標準

綠燈之後先整理命名、重複邏輯同結構。保持測試不變,可以幫你發現重構改咗已記錄嘅行為;但測試通過只代表已測嘅部分通過。

◉ 重構前核對

檢查呢次重構有冇改動已定義嘅輸入、輸出、錯誤或者副作用。

先列出預計修改同驗證方法,再做最小改動。唔好為咗令測試通過而改預期值。如果發現原有要求矛盾,停喺嗰項規則,指出矛盾例子。

冇必要為三行清晰程式再加幾層抽象。重構應該解決可指出嘅閱讀或者維護問題。

4. 舊程式同外部服務點處理?

舊程式可以先用 characterization tests 記錄目前行為,再逐步整理。不過「目前會咁做」唔等於「業務要求應該咁做」。遇到已知錯誤,要另寫修正規則,唔好永久保留錯誤答案。

外部 API、檔案系統同資料庫嘅測試,要分開純邏輯同真正接合位置。Mock 可以控制失敗條件,但 mock 通過唔代表外部服務合約冇變;仍要按風險安排整合驗證。

UI 亦可以測行為,例如鍵盤能否提交、錯誤訊息係咪可見。至於一次性匯入或者刪除腳本,執行次數少都可能影響大量資料,應先用隔離樣本、預覽結果同復原演練驗證。

5. 點知測試真係有用?

睇三件事:規則有冇獨立來源;合理嘅錯誤實作會唔會令測試失敗;失敗訊息能否指出邊項行為壞咗。

唔好用測試數量或者覆蓋率代替呢三個問題。一次修正之後,最有價值嘅新增測試通常係重現嗰個錯誤,令同類改動下次唔會靜靜地再出事。

◉

文中工具 · 連結

  • 開發者用 — terminal 入面同 Claude pair coding

睇完想同 Claude 一齊行一次?

撳一下,複製教學提示詞同全文到剪貼簿。 貼入 Claude.ai 或 Claude Desktop,再按文章逐步試做, 整理出適合你情況嘅草稿或清單;未確認嘅資料會留低畀你核對。

◉下期預告 · 相關情境
◉訂閱狀態

訂閱服務尚未開通

最新教學可直接到文章列表閱讀。