「如果你的測試案例失敗時,你無法在 3 秒內從案例名稱看懂是哪一個商業規則壞掉,那這個案例很可能包攬了太多不屬於它的責任。」
大家好,我是 Jane。
在 Day 6 我們聊到了從「單一腳本」演進到「測試框架」時需要抽離的 7 大核心要素。當我們有了基本的框架結構後,接下來每天要面對的硬功夫,就是寫出一條條「高品質、好維護」的測試案例。
剛開始寫自動化測試時,我們常會有一種直覺:
這種把整個 User Journey 塞進單一測試案例的作法,我們稱之為 「巨無霸案例(Monster Test / Long E2E)」。
在 3 個案例時這樣寫看起來很省事,但到了 30 個案例時,這種「一條龍」寫法就會變成 CI 上的災難噩夢。今天這篇文章,我們就來聊聊:一個測試案例到底該負責多少事情?
為什麼資深 QA 都強烈建議避免過長的測試案例?因為它們帶來的維護成本極其高昂:
巨無霸案例範例:
test("使用者完成購物流程", async () => {
// 步驟 1: 註冊帳號
// 步驟 2: 登入
// 步驟 3: 搜尋商品
// 步驟 4: 加購物車
// 步驟 5: 填寫地址
// 步驟 6: 付款
// 步驟 7: 檢查訂單紀錄
});
當 CI 跑出失敗時,報告只會顯示:test "使用者完成購物流程" FAILED。
你無法一眼看出到底是在「填寫地址」時彈出 Validation Error、還是在「付款」時 Timeout。你必須抓 Log、看截圖、甚至本地重跑才能知道壞在哪裡。
如果測試在第 6 步「付款」失敗,為了排查問題,你每次修完腳本重跑時,都必須重新執行前 5 個步驟。這不但浪費 CI 執行時間,也增加了測試因為網路抖動而 Flaky 的機率。
過長的案例往往伴隨著「狀態污染」。後面的驗證高度依賴前面步驟產生的資料(例如依賴上一步註冊成功生成的 User ID)。一旦前一步出錯,後面整條鏈結全部斷掉,產生一連串連鎖失敗(Cascading Failures)。
一個名稱叫 test_checkout_flow 的案例,到底是在驗證「折價券扣抵」、「運費計算」還是「信用卡格式檢查」?當一個案例驗證了 10 件不同的事,它就失去了作為「商業規格文件」的價值。
在大多數測試框架中,第一個 assert 失敗後,程式碼就會中斷執行。如果你的巨無霸案例裡驗證了「商品名稱」、「小計金額」、「稅金」與「總金額」,一旦「商品名稱」斷言失敗,後面的金額驗證根本不會執行,你無法一次掌握所有壞掉的細節。
一個好的自動化測試案例,應該遵守 AAA 模式(Arrange - Act - Assert),且符合 FIRST 原則:
┌──────────────────────────────────────────────────────────┐
│ Arrange (準備測試資料與環境) │
├──────────────────────────────────────────────────────────┤
│ Act (執行單一被測動作) │
├──────────────────────────────────────────────────────────┤
│ Assert (進行精準斷言驗證) │
└──────────────────────────────────────────────────────────┘
測試案例的名稱應該要能直接反應商業期待:
test_shopping()
test_checkout_should_apply_discount_when_using_valid_coupon()
test_checkout_should_fail_when_credit_card_expired()
將巨無霸案例拆分成數個小而專一的案例後,即便其中一個失敗,其他案例依然能正常執行,為團隊提供精確的防線情報。
「拆成小案例後,如果每個案例都要從登入、加購物車開始點,時間不會更慢嗎?」
這就是關鍵解法:只有被測試的主角需要走 UI / 操作,前置條件全部用 API 或 DB 快速預建!
有人會問:「Jane,難道我們完全不能寫任何 End-to-End 貫穿全流程的測試嗎?」
答案是:看測試的類型與層級。
在實務上,我們可以採取分層策略:
| 測試類型 | 案例粒度 | 數量比例 | 目的 |
|---|---|---|---|
| Smoke / Happy Path E2E | 貫穿主流程(全流程 1 條) | 少 (5~10%) | 部署後快速確認整個系統基本運作正常(如:能從頭到尾完成一次購買)。 |
| 功能與邏輯驗證 (Fine-grained) | 專一、小粒度(各類邊界與情境) | 多 (90%) | 驗證各種組合、錯誤處理、權限限制與金額計算,前置步驟靠 API 準備。 |
寫完一個測試案例後,試著回答這 3 個問題,檢查粒度是否適中:
討論完測試案例的責任與粒度後,接下來我們要面對的是測試程式碼本身的「維護性」。
很多 QA 會覺得「測試程式碼只要能跑就好,不用像產品程式碼那樣講究品質」。這種心態往往是測試程式碼演變成「垃圾場」的開端。
明天 Day 8,我們就來談談:《 Day 8|測試程式也需要良好的程式碼品質:別讓你的測試程式碼變成技術債 》。