讀完這章你要能回答:測試的「大小」和「範圍」是兩回事嗎?我的測試金字塔是不是其實是個甜筒?覆蓋率高就代表系統可靠嗎?
測試策略最常見的誤解,是把所有測試混為一談、用同一把尺衡量。實際上,測試有兩個彼此獨立的維度,搞清楚它們,才能設計出又快又可信的測試組合。
兩個正交維度:Size 與 Scope#
| 維度 | 分類 | 衡量的是 |
|---|---|---|
| Size(規模) | Small / Medium / Large | 測試消耗的資源與隔離程度 |
| Scope(範圍) | unit / integration / e2e | 測試涵蓋的程式碼範圍 |
- Size 關注的是「跑起來要多少資源、有多隔離」:
- Small:單一程序內、不碰網路或磁碟,毫秒級、極穩定。
- Medium:可跨程序、用本機資源(如本地 DB),秒級。
- Large:跨機器、依賴外部系統,慢且較易不穩。
- Scope 關注的是「驗證了多少程式碼」:unit 驗單一單元、integration 驗模組間協作、e2e 驗整條使用者路徑。
兩者正交:一個 unit-scope 的測試通常是 Small,但也可能因為依賴而變成 Medium。設計測試時要同時意識到這兩個軸。
測試金字塔:80 / 15 / 5#
理想的測試組合像金字塔——底層大量快速的小測試,往上逐漸減少。
flowchart TB
E["🔺 e2e ~5%<br/>慢、貴、脆弱"]
I["🔷 integration ~15%<br/>驗模組協作"]
U["🟩 unit ~80%<br/>快、穩、便宜"]
E --> I --> U
style E fill:#ffcdd2
style I fill:#fff3e0
style U fill:#c8e6c9大約 80% unit / 15% integration / 5% e2e 是健康的基準。底層測試快又穩,能快速定位問題;頂層測試貴又脆,只用在驗證關鍵端到端路徑。
兩個常見的反模式:
- 冰淇淋甜筒(ice-cream cone):頭重腳輕,大量 e2e、極少 unit。測試慢、易壞、難除錯,是金字塔的倒置。
- 沙漏(hourglass):unit 與 e2e 都多、integration 嚴重不足。模組間的整合問題會在最貴的 e2e 層才被發現。
覆蓋率不等於信心#
覆蓋率(coverage)衡量的是「程式碼被執行到」,不是「行為被驗證了」。100% 覆蓋率的測試套件,完全可能沒有任何一個有意義的斷言。把覆蓋率當成目標,人們就會寫「跑過但什麼都不檢查」的測試來衝數字。覆蓋率是診斷工具(找出完全沒被測到的區塊),不是品質目標。
兩條穩定性與責任歸屬的原則:
- Flake 上限 ~0.15%:不穩定(flaky)的測試會慢慢侵蝕信任。把不穩定率控制在 0.15% 以下;一旦超過 ~1%,工程師就會開始無視紅燈、隨手 retry,整套測試的價值瞬間崩塌。
- Beyoncé Rule:「If you liked it, you should have put a test on it.」——如果你在乎某個行為不能壞,就為它寫一個測試。否則別人重構時弄壞它,責任不在重構的人,而在沒有把它鎖進測試的你。
本章要點#
- 兩個正交維度:Size(資源/隔離)× Scope(覆蓋範圍)是兩回事。
- 金字塔 80/15/5:底層大量快測,頂層少量端到端。
- 避開甜筒與沙漏:頭重腳輕或中段塌陷都會讓測試慢且脆。
- 覆蓋率 ≠ 信心:它衡量執行到、不衡量驗證了,別當目標。
- 管好 flake:控制在 ~0.15% 以下,超過 ~1% 就會摧毀信任。
- Beyoncé Rule:在乎它不壞,就為它寫測試。