測試金字塔

是什麼?

測試金字塔(Test Pyramid)是 Mike Cohn 在《Succeeding with Agile》中提出的模型,描述不同層級測試的理想比例和策略。

ℹ️指導原則,不是教條

測試金字塔是一個思考模型,不是精確的比例公式。重點是「底層多、頂層少」的原則,具體數字依專案調整。

核心觀念

常見誤區

⚠️失衡的測試策略

  • 冰淇淋甜筒反模式:只寫 E2E 不寫單元測試,CI 跑一次要 30 分鐘,開發者不敢跑
  • 只寫單元測試:每個函式都測了,但元件接起來就爆——因為沒有整合測試
  • 追求 100% 覆蓋率:覆蓋率是指標,不是目標。100% 覆蓋率不代表 0 個 Bug
  • 每層使用相同的工具:不同層級適合不同工具,不要用 E2E 工具寫單元測試

金字塔層級

1

Unit Test(底層)

大量、快速、便宜。測試單一單元的邏輯,毫秒級完成。佔比約 70%

2

Integration Test(中層)

適量、中速。測試元件間的互動與整合,秒級完成。佔比約 20%

3

E2E Test(頂層)

少量、慢速、昂貴。模擬完整使用者流程,分鐘級完成。佔比約 10%

程式碼範例

C#(xUnit)

csharp
// Unit Test — 快速,只測邏輯
public class PriceCalculatorTests
{
    [Fact]
    public void CalculateDiscount_VipCustomer_Gets20PercentOff()
    {
        var calculator = new PriceCalculator();
        var result = calculator.CalculateDiscount(100m, CustomerType.Vip);
        Assert.Equal(80m, result);
    }
}
 
// Integration Test — 測 API + Database 的互動
public class OrderApiTests : IClassFixture<WebApplicationFactory<Program>>
{
    private readonly HttpClient _client;
 
    public OrderApiTests(WebApplicationFactory<Program> factory)
    {
        _client = factory.CreateClient();
    }
 
    [Fact]
    public async Task CreateOrder_ValidRequest_ReturnsCreated()
    {
        var content = JsonContent.Create(new { ProductId = 1, Quantity = 2 });
        var response = await _client.PostAsync("/api/orders", content);
        Assert.Equal(HttpStatusCode.Created, response.StatusCode);
    }
}
 
// E2E Test — 用 Playwright 模擬使用者
// (通常放在獨立的測試專案)
// [Fact]
// public async Task User_CanCompleteCheckout()
// {
//     await page.GotoAsync("https://localhost:5001");
//     await page.ClickAsync("[data-testid='add-to-cart']");
//     await page.ClickAsync("[data-testid='checkout']");
//     await Expect(page.Locator(".success-message")).ToBeVisibleAsync();
// }

TypeScript(Jest)

typescript
// Unit Test — 只測純邏輯
describe("PriceCalculator", () => {
  it("gives VIP 20% discount", () => {
    const calculator = new PriceCalculator();
    expect(calculator.calculateDiscount(100, "vip")).toBe(80);
  });
});
 
// Integration Test — 測 API endpoint
describe("POST /api/orders", () => {
  it("creates order and returns 201", async () => {
    const response = await request(app)
      .post("/api/orders")
      .send({ productId: 1, quantity: 2 });
 
    expect(response.status).toBe(201);
    expect(response.body.id).toBeDefined();
  });
});

Python(pytest)

python
# Unit Test — 只測純邏輯
def test_calculate_discount_vip_gets_20_percent_off():
    calculator = PriceCalculator()
    result = calculator.calculate_discount(100, CustomerType.VIP)
    assert result == 80
 
# Integration Test — 測 API + Database
def test_create_order_valid_request(client, db):
    response = client.post("/api/orders", json={
        "product_id": 1,
        "quantity": 2
    })
    assert response.status_code == 201
    assert db.query(Order).count() == 1

概念圖

測試金字塔
底層:大量、快速
Unit Test (70%)
Integration Test (20%)
E2E Test (10%)
Testing Trophy
強調整合測試價值
冰淇淋甜筒 (反模式)

此圖呈現三種模型的關係:傳統金字塔強調 Unit Test 為基礎,Testing Trophy 把重心移到 Integration Test,而冰淇淋甜筒是大家都該避免的反模式。沒有哪個模型是絕對正確的——前端專案偏向 Trophy,後端 API 偏向傳統金字塔。

不同專案類型的比例建議

| 專案類型 | Unit | Integration | E2E | 說明 | |----------|------|-------------|-----|------| | 後端 API | 70% | 25% | 5% | 商業邏輯多,Unit Test 價值最高 | | 前端 SPA | 30% | 50% | 20% | 偏向 Testing Trophy,Integration Test 驗證元件互動 | | 微服務 | 50% | 40% | 10% | 服務間整合是主要風險,Integration Test 比重高 | | CLI 工具 | 80% | 15% | 5% | 以純邏輯為主,Unit Test 覆蓋最有效 |

實戰補充

💡資深開發者的經驗

  • Testing Trophy 的觀點:Kent C. Dodds 認為 Integration Test 的投資報酬率最高,因為它能捕捉到真實的使用者流程,又不像 E2E 那麼慢。
  • 每層的回饋速度不同:Unit Test 在開發時即時回饋(秒級),Integration Test 在 CI 回饋(分鐘級),E2E 在部署前回饋(十分鐘級)。
  • 團隊規模影響比例:小團隊可能偏向 Testing Trophy(更多 Integration),大團隊需要更嚴格的 Unit Test 保護。
  • Flaky Test 是殺手:E2E 層最容易出現不穩定的測試。如果 E2E 每次都隨機失敗,團隊會開始忽略測試結果。

理解測驗

🤔 測試金字塔建議哪一層的測試數量最多?

🤔 什麼是冰淇淋甜筒反模式?

🤔 Testing Trophy 和傳統測試金字塔的主要差異是什麼?

重點整理

💡一句話記住

口訣:「底廣頂尖像金字塔,快的多寫慢的少寫,倒過來就是甜筒災難」。

| 層級 | 速度 | 信心度 | 成本 | 建議比例 | |------|------|--------|------|----------| | Unit Test | 毫秒 | 低(只測單元) | 低 | ~70% | | Integration Test | 秒 | 中(測互動) | 中 | ~20% | | E2E Test | 分鐘 | 高(測全流程) | 高 | ~10% |

你可能也想看

單元測試最佳實踐整合測試

按 ← → 鍵切換課程