> 九號工具站
返回列表

Test Pyramid + 完整測試類型全圖 — Unit / Integration / E2E / Smoke / Sanity / Regression 一次說清

一篇講完所有測試類型。Test Pyramid 三層、Smoke vs Sanity 差別、Regression 策略、Shift-left vs Shift-right、現代變形(Trophy、Honeycomb)。

QA test-pyramid testing-types test-strategy fundamentals
· 最後更新 2026-06-12 · 最後審閱 2026-08-30

💡 本文原刊於 qa.9niche.com,2026-08 併入 9niche.com 懶人包,內容照原文完整搬遷。

1. 前言

「Smoke 跟 sanity 差在哪?」「Regression 跟 acceptance 是同個東西嗎?」是 QA 面試最常被搞混的問題。這篇用一張圖把所有測試類型講清楚 — 該寫多少、什麼時候跑、誰寫、為什麼。

2. 經典 Test Pyramid(Mike Cohn)

比例速度抓什麼寫的人
Unit70%< 100ms邏輯錯Dev
Integration25%5-30s元件契約Dev + QA
E2E5%1-30min使用者流程QA

為什麼是金字塔形狀

  • 底層多:unit test 多、跑快、抓 bug 早、修便宜
  • 上層少:E2E 慢、貴、flaky 風險高、只測 critical path

反金字塔(多 E2E 少 unit)= 開發地獄

flowchart TB subgraph Pyramid E2E["🔺 E2E Tests<br>少 - 5%<br>慢 - 1-30 min<br>跨整個 stack"] Int["▱ Integration Tests<br>中 - 25%<br>中 - 5-30s<br>多元件互動"] Unit["⬛ Unit Tests<br>多 - 70%<br>快 - <100ms<br>純函式邏輯"] end E2E --> Int Int --> Unit style E2E fill:#ef4444,color:#fff style Int fill:#f59e0b,color:#fff style Unit fill:#10b981,color:#fff

3. Smoke / Sanity / Regression / Acceptance 一次看懂

類型跑什麼何時多久
Smoke最基本可用性(登入 / 首頁 / 結帳 happy path)每次 build 進5-15 min
Sanity剛改的功能 + 直接相關改某 module 後15-30 min
Regression所有舊功能發版前1-4 hr
AcceptanceUser Story / Acceptance CriteriaSprint end30 min - 2 hr

區分 Smoke vs Sanity

最容易搞混

Smoke:「This build runs」(廣度淺、確認基本可用)
Sanity:「This change works」(深度但窄、確認改的對)

例子:

Dev 改了「結帳」功能 → push code

Smoke: 開首頁、登入、加購物車、結帳 — happy path 完整跑
Sanity: 結帳 form 各欄位驗證、信用卡輸入、優惠券、發票
flowchart LR Build[Code 進來] --> Smoke[Smoke Test<br>還能跑嗎?] Smoke -->|過| Sanity[Sanity Test<br>剛改的 OK 嗎?] Sanity -->|過| Reg[Regression<br>舊的沒壞?] Reg -->|過| Accept[Acceptance<br>使用者要的有嗎?] Accept -->|過| Release[發版] Smoke -->|fail| Stop1[Build 不能用] Sanity -->|fail| Stop2[改壞了] Reg -->|fail| Stop3[影響舊功能] Accept -->|fail| Stop4[不符需求] style Smoke fill:#06b6d4,color:#fff style Sanity fill:#a855f7,color:#fff style Reg fill:#10b981,color:#fff style Accept fill:#f59e0b,color:#fff

4. 現代變形:Testing Trophy

Kent C. Dodds 提的、適合前端 React 應用

  • Static(TypeScript / ESLint)佔底
  • Integration(React Testing Library)變主力
  • Unit 變少(純函式還是寫)
  • E2E 還是少

理由:前端的「unit」很難純粹、integration 更有 ROI

flowchart TB subgraph Trophy E2E2["🔺 E2E<br>少"] Int2["▱▱▱ Integration<br>多 - 主力"] Unit2["▱ Unit<br>中"] Static["⬜ Static<br>底 - linter/type"] end style E2E2 fill:#ef4444,color:#fff style Int2 fill:#10b981,color:#fff style Unit2 fill:#06b6d4,color:#fff style Static fill:#a855f7,color:#fff

5. 現代變形:Testing Honeycomb

Spotify 提的、適合微服務

  • 大量 integration test(服務間互動)
  • 少量 unit(純邏輯)
  • 少量 E2E(critical flow)

重點:金字塔不是唯一答案、看你的 stack 與痛點。

flowchart TB subgraph Honeycomb UI["◇ UI tests<br>少"] Implementation["◇◇◇ Integration tests<br>主力"] Detail["◇ Implementation detail tests<br>少"] end style UI fill:#ef4444,color:#fff style Implementation fill:#10b981,color:#fff style Detail fill:#06b6d4,color:#fff

6. 8 種測試「型」一次看懂

mindmap root((測試類型)) Functional 功能 Unit Integration E2E System Acceptance Non-functional 非功能 Performance Security Accessibility Usability Compatibility 時機 Smoke Sanity Regression Confirmation 技法 Black box White box Gray box 階段 Static analysis Dynamic Manual Automation Exploratory Session-based Charter-driven Pair testing Production Canary A/B Feature flag Synthetic monitoring 特殊 Chaos Mutation Property-based Snapshot / Visual

7. 功能測試(Functional)

Unit Test

# 純函式、無外部依賴
def test_calculate_discount():
    assert calculate_discount(100, 0.1) == 90
  • 速度:最快(毫秒級)
  • 範圍:單一函式
  • Mock 外部依賴

Integration Test

# 多個元件互動
def test_create_order_via_api(db, mock_payment):
    resp = client.post('/orders', json={...})
    assert resp.status_code == 201
    assert Order.objects.count() == 1
    mock_payment.assert_called_once()
  • 速度:中(秒級)
  • 範圍:多元件
  • DB / Redis / API 真連、外部第三方 mock

E2E (System Test)

// 跨整個 stack
test('user can checkout', async ({ page }) => {
  await page.goto('/');
  await page.click('text=加入購物車');
  // ... 完整流程
  await expect(page).toHaveURL('/order-success');
});
  • 速度:慢(分鐘級)
  • 範圍:整個系統
  • 全程真實

Acceptance Test

驗證 business 是否接受

User Story: 使用者買 3 件以上 9 折
Acceptance Criteria:
  - 2 件無折扣
  - 3 件 9 折
  - 5 件 9 折(不疊加)
  - 跨類別也算

Confirmation Test

Bug 修了後確認真的修好跟 regression 不同 — confirmation 是針對該 bug。

8. 非功能測試(Non-functional)

Performance Test

延伸閱讀:Performance Testing 入門

子類型:

  • Load Test(正常量)
  • Stress Test(超量找崩潰點)
  • Spike Test(突發爆量)
  • Soak Test(長時間找 memory leak)

Security Test

延伸閱讀:Security Testing OWASP

子類型:

  • Penetration Testing
  • Vulnerability Scan
  • Auth / Permission Test
  • Static Application Security Test (SAST)
  • Dynamic Application Security Test (DAST)

Accessibility (a11y)

  • WCAG 標準(A / AA / AAA)
  • Screen reader compatibility
  • Keyboard navigation
  • 顏色對比度
  • 工具:axe / Lighthouse / Wave

Usability Test

  • 真實使用者操作
  • 觀察 friction 點
  • A/B test 變體
  • User journey map

Compatibility Test

  • 跨瀏覽器(Chrome / Firefox / Safari / Edge)
  • 跨裝置(iOS / Android / Windows / Mac)
  • 跨螢幕尺寸
  • 跨網路(4G / WiFi / 慢速)
  • 跨語系 / 地區

9. 技法(Technique)

flowchart LR Tech[測試技法] --> BB[Black Box<br>不看 code] Tech --> WB[White Box<br>看 code] Tech --> GB[Gray Box<br>知道一些] BB --> BB1[等價分割] BB --> BB2[邊界值] BB --> BB3[決策表] BB --> BB4[狀態轉換] WB --> WB1[Statement coverage] WB --> WB2[Branch coverage] WB --> WB3[Path coverage] GB --> GB1[API + DB 知道結構] GB --> GB2[Detox 灰盒] style BB fill:#06b6d4,color:#fff style WB fill:#10b981,color:#fff style GB fill:#a855f7,color:#fff

10. Shift-Left vs Shift-Right

Shift-Left(往左 — 早抓)

  • Spec review
  • TDD / BDD
  • Pair programming
  • Pre-commit hooks
  • 早期 unit test

抓 bug 在 dev 階段

Shift-Right(往右 — Prod 測)

  • Canary release(1% 流量試)
  • Blue / Green
  • Feature flags
  • A/B testing
  • Real-user monitoring
  • Synthetic monitoring

真實環境抓 dev 抓不到的事

現代 QA:兩個都做。

flowchart LR Old[傳統] --> O1[Dev 寫] --> O2[QA 測] --> O3[發版] --> O4[Prod] SL[Shift-Left] --> SL1[Spec review] --> SL2[Dev + Test 一起寫] --> SL3[CI 早抓] SR[Shift-Right] --> SR1[Canary deploy] --> SR2[A/B test] --> SR3[Production monitoring] style Old fill:#9ca3af,color:#fff style SL fill:#06b6d4,color:#fff style SR fill:#a855f7,color:#fff

11. Production Testing

Netflix 等大公司:testing in production 是日常。

flowchart TD Prod[Production Testing] --> P1[Synthetic monitoring<br>定時跑 happy path] Prod --> P2[Canary deploy<br>1% 流量先試] Prod --> P3[Feature flag<br>內部先開] Prod --> P4[A/B test<br>對照組] Prod --> P5[Chaos engineering<br>故意搞破壞] Prod --> P6[Real-user monitoring<br>看真實 metric] style Prod fill:#ef4444,color:#fff

12. 特殊類型

Mutation Testing

測試你的 test 好不好

工具改你的 code(mutate)、看 test 抓不抓得到。

// 原 code
function isAdult(age) { return age >= 18; }

// Mutant 1
function isAdult(age) { return age > 18; }  // 改 >= 為 >

// 如果你的 test 還是 pass → test 不夠好
// 工具: Stryker (JS), PIT (Java), mutmut (Python)

Property-based Testing

不寫具體 case、寫「規律」。

from hypothesis import given, strategies as st

@given(st.lists(st.integers()))
def test_reverse_twice_is_identity(lst):
    assert reverse(reverse(lst)) == lst

Hypothesis 會自動產 100 個 case 試。

Visual Regression

比對 screenshot 差異。

await expect(page).toHaveScreenshot('homepage.png');

工具:Playwright snapshot / Percy / Applitools / Chromatic

Snapshot Testing

把 component 渲染結果存檔、改了就 diff。

// Jest
expect(render(<Button />).toJSON()).toMatchSnapshot();

Chaos Engineering

故意搞破壞、看系統撐不撐。

  • 隨機 kill pod
  • 切斷網路
  • 延遲增加
  • DB 過載

工具:Chaos Monkey / Litmus / Chaos Mesh

13. 該怎麼選

flowchart TD Q[要測什麼?] --> Q1{業務邏輯<br>對嗎?} Q --> Q2{多元件<br>協作?} Q --> Q3{使用者<br>體驗?} Q --> Q4{快不快?} Q --> Q5{安全嗎?} Q1 --> Unit Q2 --> Integration Q3 --> E2E Q4 --> Perf[Performance] Q5 --> Sec[Security] style Unit fill:#10b981,color:#fff style Integration fill:#f59e0b,color:#fff style E2E fill:#ef4444,color:#fff style Perf fill:#a855f7,color:#fff style Sec fill:#06b6d4,color:#fff

14. QA 在每層的角色

Unit: Dev 寫。QA 看 coverage、推動寫。
Integration: Dev + QA 一起。QA review test scenario。
E2E: QA 主力。Dev 偶爾協助。
Smoke: 自動化、QA 設計、CI 跑。
Regression: QA 維護 + 自動化、Release 跑。
Acceptance: QA 主導、PM 簽核。
Performance / Security / A11y: 特定 QA 或 specialist。
Exploratory: QA 個人能力。

15. 反模式

flowchart TD Anti[Pyramid 反模式] --> A1["反金字塔:100 個 E2E 0 個 unit"] Anti --> A2["E2E 占 50%:跑半天"] Anti --> A3["只看 coverage % 數字"] Anti --> A4["smoke 寫太細:變 regression"] Anti --> A5["regression 不維護:越跑越爛"] Anti --> A6["不分 unit/integration、混在一起"] Anti --> A7["完全沒 shift-right"] style A1 fill:#ef4444,color:#fff style A2 fill:#ef4444,color:#fff style A3 fill:#ef4444,color:#fff style A4 fill:#ef4444,color:#fff style A5 fill:#ef4444,color:#fff style A6 fill:#ef4444,color:#fff style A7 fill:#ef4444,color:#fff

16. 面試考題

Q: 解釋 Test Pyramid

好答案

由下而上 unit(最多)、integration、E2E(最少)。底層多因為快、便宜、抓邏輯 bug;上層少因為慢、貴、易 flaky。比例約 70/25/5。但這是經典 — 現代有變形如 Testing Trophy(前端)跟 Honeycomb(微服務)— 重點是依 stack 跟痛點選比例。

Q: Smoke 跟 sanity 差在哪

好答案

Smoke 是「廣度淺」確認 build 還能用;sanity 是「深度窄」確認剛改的功能對。Smoke 每次 build 跑、sanity 改某模組後跑。

Q: 你怎麼決定要寫 unit 還是 E2E

好答案

看抓的 bug 類型。純邏輯 / 純函式 → unit;多元件契約 / 服務間 → integration;使用者完整流程 → E2E。原則:能在底層抓就在底層抓、E2E 留 critical path。

17. 給 QA 的 5 句

  1. Pyramid 不是 dogma、是 starting point
  2. 每個類型該寫多少看你的 stack + 痛點
  3. Smoke vs Sanity vs Regression 分清楚是 process 健康指標
  4. Shift-left + Shift-right 兩個都要
  5. 比起背名詞、設計合適你 team 的測試組合更重要

18. 最後

懂測試類型的 framework 不是炫術語、是幫你決定該寫什麼、跑什麼、跳過什麼。team 沒 unit test → 推 dev 開始寫;E2E 過多 → 改成 integration;regression 越跑越慢 → 分 smoke + 主力。理論工具拿來解現實問題、才有價值

ℹ️

一般聲明

本站提供之資訊僅供參考,不保證其完整性與正確性。使用者應自行判斷資訊之適用性。

意見反饋