principle-test-behavior-not-implementation | 測試使用者可觀察的契約
本頁以 pstack-claude 0.9.126 為基準。原文設定 user-invocable: false,通常由 poteto-mode 按需讀取。這項原則用來判斷測試是否真的保護行為。
定位與適用情境
行為是呼叫者、終端使用者或其他服務經由介面可以觀察的結果。包含回傳值、可讀回狀態、錯誤及外部副作用。私有輔助函式、內部協作者與中間資料通常不是契約。
例如結帳流程要求「空購物車不可扣款,非空購物車依總額扣款一次」。只確認內部 calculateTotal 被呼叫,無法證明沒有重複扣款。反過來,驗證支付服務收到的金額與次數,就是外部可觀察行為。
準備
- 提供公開結帳入口、空購物車規則、非空購物車總額規則與支付介面契約。
- 準備空購物車,以及一件商品、數量二、單價
300的購物車,依需求算出總額600。 - 使用支付沙箱或在外部服務邊界設置測試替身(test double),可觀察送出的請求,但不實際扣款。不要只模擬內部輔助函式。
操作步驟
- 從使用者實際使用的結帳介面送入空購物車,斷言支付邊界沒有收到扣款請求,並檢查規格承諾的結果或錯誤。
- 從同一介面送入非空購物車,斷言支付邊界收到一次金額
600的請求。這個正向案例也證明觀察器看得到請求,不是無論如何都回報零次。 - 在隔離測試中驗證「破壞行為」的假想修改。若漏扣款、金額錯誤或扣款兩次,測試應因對應契約不符而失敗。預期金額不能由被測程式重新計算。
- 再檢查「只改內部」的修改,例如合併輔助函式或調整不影響輸出的計算順序。測試應保持通過。若失敗只因私有函式名稱或呼叫順序改變,就重新設計斷言。
可直接使用的提示詞
套用 principle-test-behavior-not-implementation,檢查結帳測試是否保護公開契約。
需求是空購物車不扣款,兩件單價 300 的商品扣款一次且總額為 600。
從公開結帳入口執行,用支付沙箱或外部邊界替身觀察請求,不實際扣款。
同時保留零次與一次扣款案例,確認漏扣、重扣及錯額會被抓到。
指出只改內部結構時哪些斷言應保持通過,勿用內部 mock 呼叫代替行為證據。
先提出測試調整方案,不修改或刪除現有測試。
預期結果與驗收
- 空購物車不產生扣款,非空購物車只產生一次正確金額的扣款請求。
- 漏扣、重扣與錯額都使對應測試失敗,不是只剩「有回傳東西」的寬鬆斷言。
- 內部輔助函式重組不改外部結果時,測試不用跟著改寫。
- 斷言來自需求,不是測試自行組裝的資料,或被測程式自己提供的答案。
限制與權限
常見誤用是認為「行為測試」等於禁止任何 mock,或反過來只檢查內部 mock 呼叫。重點在介面契約。支付服務收到的請求可作行為證據,內部函式被呼叫則通常不行。
錯誤型別若供呼叫者分支判斷,就屬契約;未承諾的錯誤文案不必逐字鎖定。跨表不變條件、編譯期檢查與有文件承諾的預設值也可能是行為,不限定只能測畫面。
本頁沒有扣款、修改或刪除測試。替身驗證不等於正式支付整合已通過,仍須交代覆蓋邊界。改寫或刪除既有測試需依實際任務授權。