測試類型全解

是什麼?(測試類型為何要分這麼多種)

身為資深 C# 開發者,你一定寫過 xUnit 的 [Fact],也跑過整個系統的端對端冒煙。這些「測試」表面上都是在驗證程式,但它們回答的問題、執行的時機、由誰負責、跑起來多快多貴,差異極大。

把測試分類的核心理由,是讓團隊能在不同抽象層級回答不同問題:

分類不是學術潔癖,而是讓你能有意識地分配測試投資:哪些要多寫、哪些要少寫、哪些要自動化、哪些必須人工。這份課程就是測試類型的「地圖」。

ℹ️本課定位

這課聚焦在「有哪些測試類型、各是什麼、怎麼比較、何時用」。至於「如何制定測試策略、產出測試報告與覆蓋率指標」,請見站上的測試策略與報告課程,兩者互補。

兩大分類:功能性 vs 非功能性測試

最頂層的分類,是問測試在驗證「行為」還是「品質屬性」。

維度功能性測試非功能性測試
回答的問題系統「做了什麼」對不對系統「做得好不好」
依據功能規格、需求品質屬性、SLA、NFR
例子登入成功會導向首頁一萬人同時登入仍 1 秒內回應
典型類型單元、整合、系統、E2E、UAT效能、安全、可用性、相容性

功能性測試問「對不對」,非功能性測試問「夠不夠好」。兩者都會失敗讓使用者離開,只是離開的理由不同。

功能性測試逐一詳解

下面每一種都從四個角度說明:定義、測什麼、誰做、何時做

1

單元 Unit

驗證單一方法或類別的邏輯,隔離外部相依

2

整合 Integration

驗證多個模組或外部資源(DB、API)接起來能運作

3

系統 System

以完整系統為對象,驗證是否符合規格

4

端對端 E2E

模擬真實使用者,從 UI 走完整流程

5

驗收 UAT

由真實使用者驗收是不是他要的

單元測試(Unit Test)

整合測試(Integration Test)

系統測試(System Test)

端對端測試(E2E Test)

驗收測試/UAT(User Acceptance Test)

冒煙測試(Smoke Test)

健全測試(Sanity Test)

回歸測試(Regression Test)

💡冒煙 vs 健全 vs 回歸

冒煙是「廣而淺」決定要不要測下去;健全是「窄而深」驗剛改的點;回歸是「廣而深」確認沒退步。三者目的不同,別混為一談。

非功能性測試

功能對了,不代表系統能用。非功能性測試驗證的是品質屬性(NFR)。

類型驗證什麼典型問題
效能 Performance回應時間、吞吐量在預期負載下夠快嗎
負載 Load預期尖峰下的表現雙十一流量撐得住嗎
壓力 Stress超過極限後的行為崩潰時是否優雅降級而非雪崩
安全 Security漏洞與權限能否被 SQL Injection 或越權存取
可用性 Usability操作直覺度使用者找得到按鈕嗎
可存取性 Accessibility無障礙支援螢幕報讀器、鍵盤可操作嗎
相容性 Compatibility跨環境一致各瀏覽器、OS、裝置都正常嗎
可靠性 Reliability長時間穩定連續運行三天會記憶體洩漏嗎

ℹ️負載與壓力的差別

負載測試問「在我預期的最大流量下還順嗎」;壓力測試刻意把流量推過天花板,看系統「壞掉時壞得好不好看」(是否優雅降級、能否自動恢復)。

測試金字塔與重要性權衡

測試金字塔(Test Pyramid)告訴你各層級該寫多少量

E2E/UI(少)
往下越多
整合測試(適中)
越快越穩
單元測試(最多)

為什麼底層多、上層少?因為越往下:

冰淇淋甜筒反模式(Ice-cream Cone) 是金字塔倒過來:大量手動與 E2E 測試、極少單元測試。結果是測試又慢又脆、回饋遲緩、維護成本爆炸。很多團隊在「補測試」時不小心就堆成了甜筒。

🤔 團隊發現 CI 跑得很慢且測試常常隨機失敗(flaky),追查後發現大量測試都是透過瀏覽器走完整流程,單元測試卻寥寥無幾。這是什麼反模式?

各類型一覽比較

類型層級速度成本誰負責自動化程度何時跑
單元最低極快開發者全自動每次 build
整合開發/QA全自動CI
系統中高QA半至全自動測試環境就緒後
E2E最高很慢QA/開發自動(易脆)發布前
冒煙跨層QA/CI自動每次部署後第一步
健全視範圍QA多為手動收到小修補後
回歸跨層中至慢CI 為主盡量自動每次變更後
UAT業務使用者/PO多為手動上線前

UAT 專段

UAT=User Acceptance Testing,使用者驗收測試,是上線前由真實使用者或業務代表執行的最後一道關卡。

和系統測試的關鍵差別(面試常考):

系統測試:做得對不對
通過規格後才問需求
UAT:是不是真正要的

規格可能本身就寫錯,所以系統測試全綠、UAT 卻不通過,是完全可能而且很常見的情況。

Alpha 與 Beta:

誰來測、驗收標準: UAT 由終端使用者、產品負責人或業務單位執行,依事先約定的驗收標準(Acceptance Criteria) 逐條確認。標準通常以業務語言寫成,例如「主管能在一個畫面核准請假並收到通知」。

🤔 系統測試所有案例都通過了,但 UAT 階段業務說「這不是我要的東西」。最合理的解釋是?

C# 範例(xUnit)

下面用同一個情境,對照單元測試與整合測試的差別。注意單元測試把相依隔離掉,整合測試則真的碰外部資源。

csharp
// 受測對象:下單服務
public class OrderService
{
    private readonly IInventoryRepository _inventory;
    public OrderService(IInventoryRepository inventory) => _inventory = inventory;
 
    public bool TryPlaceOrder(string sku, int qty)
    {
        if (qty <= 0) return false;
        var stock = _inventory.GetStock(sku);
        return stock >= qty;
    }
}
csharp
// 單元測試:用 mock 隔離資料庫,只驗 OrderService 的邏輯
public class OrderServiceUnitTests
{
    [Theory]
    [InlineData(5, 3, true)]   // 庫存足夠
    [InlineData(5, 10, false)] // 庫存不足
    [InlineData(5, 0, false)]  // 數量非法
    public void TryPlaceOrder_ChecksStockCorrectly(int stock, int qty, bool expected)
    {
        var repo = new Mock<IInventoryRepository>();
        repo.Setup(r => r.GetStock("SKU-1")).Returns(stock);
        var sut = new OrderService(repo.Object);
 
        var result = sut.TryPlaceOrder("SKU-1", qty);
 
        Assert.Equal(expected, result);
    }
}
csharp
// 整合測試:接真實 DB(測試容器),驗 Repository 與資料庫的協作
public class InventoryRepositoryIntegrationTests : IClassFixture<SqlServerFixture>
{
    private readonly string _connectionString;
    public InventoryRepositoryIntegrationTests(SqlServerFixture fx)
        => _connectionString = fx.ConnectionString;
 
    [Fact]
    public void GetStock_ReadsSeededRowFromDatabase()
    {
        // 前置:資料庫已 seed 一筆 SKU-1 庫存 7
        var repo = new InventoryRepository(_connectionString);
 
        var stock = repo.GetStock("SKU-1");
 
        Assert.Equal(7, stock); // 真的查到資料庫的值
    }
}

重點對照:單元測試毫秒級、無外部相依、可大量寫;整合測試較慢、需真實 DB、驗的是接線正確

常見誤區

⚠️這些坑很多資深團隊也會踩

  • 只寫單元測試、沒有整合測試:每個零件單獨都對,組起來卻在交易邊界、序列化或連線設定上爆炸。單元全綠不代表系統能跑。
  • E2E 過多導致脆弱:把驗證重擔壓在 UI 層,CI 變慢、測試 flaky,最後團隊乾脆把紅燈當噪音忽略——比沒測試還危險。
  • 把 UAT 當成 QA 的事:UAT 的主角是「使用者/業務」,不是測試工程師。讓 QA 代替使用者驗收,等於沒驗收,上線後才發現「做的不是要的」。
  • 混淆系統測試與 UAT:以為系統測試過了就等於使用者會滿意,忽略了規格本身可能就錯。

實戰補充(Q&A)

Q:回歸測試怎麼自動化? 把過去出過 bug 的案例與關鍵路徑沉澱成自動化測試套件,掛進 CI,每次 commit/PR 觸發。策略上以單元與整合測試承擔大部分回歸(快又穩),E2E 只覆蓋最關鍵旅程。修了一個 bug,就補一條對應的回歸測試,避免同一個洞再掉進去。

Q:該寫多少 E2E? 依金字塔精神,E2E 應精選而非全面:只覆蓋「壞了就會出大事」的關鍵業務流程(登入、結帳、付款)。其餘邏輯下推到單元與整合層去驗。一個常見的健康訊號是:當你想用 E2E 去測一個分支邏輯時,多半代表那段邏輯應該被往下挪到單元測試。

理解測驗

🤔 哪一組描述正確對應了「冒煙測試」的定位?

🤔 關於測試金字塔,下列何者最正確?

重點整理

💡一句話記住

單元驗邏輯、整合驗接線、系統驗規格、UAT 驗需求;金字塔底大頂小,回歸保你不退步。系統測試問「做得對不對」,UAT 問「是不是真正要的」。

你想回答的問題該用的測試
這個方法邏輯對嗎單元
模組組起來能運作嗎整合
整個系統符合規格嗎系統
真實流程從頭到尾通嗎E2E
這版能不能繼續測冒煙
剛改的點合理嗎健全
原本好的有沒有被改壞回歸
是不是使用者真正要的UAT
夠不夠快、安不安全、撐不撐得住非功能性(效能/安全/負載等)

你可能也想看

Git 分支與合併策略測試策略與測試報告

按 ← → 鍵切換課程