測試、驗收與品質保證

用不同層級的證據,判斷修改是否正確且適合交付

用不同層級的證據,判斷修改是否正確且適合交付

測試不是最後才做的階段

需求 → 寫驗收條件
設計 → 找風險與測試邊界
實作 → 執行快速自動測試
整合 → 驗證模組與完整流程
部署 → smoke test 與 production verification
維運 → regression 與事故案例

Test Pyramid

層級 特性
Unit test 快速、隔離、定位容易、數量多
Integration test 驗證資料庫、服務與模組整合
E2E test 接近真實流程,但慢、維護成本高
Manual/Exploratory 發現自動案例沒有想到的問題

Unit Test

  • 一次聚焦一個小範圍行為
  • Arrange、Act、Assert
  • 測輸入、輸出、狀態與錯誤
  • 避免過度依賴內部實作細節
  • 快速執行,適合在每次修改後重跑

Integration Test

  • 應用程式與資料庫的實際整合
  • Service、queue、cache、filesystem、external API
  • Schema、transaction、serialization 與設定
  • 使用 test container、sandbox 或專用測試環境
  • 確認 component 單獨正確後,接起來仍然正確

E2E 與 Acceptance Test

  • 從使用者入口走過完整流程
  • 對照 acceptance criteria 與 Definition of Done
  • 驗證角色、權限、畫面、API 與資料結果
  • 保留少量最關鍵的 happy path 與 failure path
  • 失敗時要能取得 screenshot、log、trace 或錄影

Test Double

類型 用途
Stub 回傳預先設定的結果
Mock 驗證某個互動是否發生
Fake 用較簡化但可工作的實作替代
Spy 記錄實際呼叫,供後續檢查

Mock 太多可能讓測試只驗證自己想像的系統。

測試資料與環境

  • Fixture、factory、seed 與 golden dataset
  • 測試必須可重複、互相隔離、可清理
  • 個資與正式資料需要遮罩或合成
  • 時間、隨機數與外部服務要可控制
  • 測試環境要盡量接近正式環境的關鍵條件

Boundary、Negative 與 Failure Case

  • 空值、極值、格式錯誤與重複輸入
  • 沒有權限、憑證過期與跨角色存取
  • Timeout、網路中斷、服務降級與部分失敗
  • 並行更新、重試、順序改變與重複訊息
  • 資料 migration 中與不同版本共存

Regression Test

  • Bug 修好後先建立能重現問題的測試
  • 新功能不能破壞既有關鍵行為
  • 依風險選擇每次 commit、PR、nightly 或 release 執行
  • 追蹤 flaky test,不讓失敗警報失去可信度
  • 測試案例也需要 review、重構與淘汰

Coverage 不是品質本身

  • Line/branch coverage 只表示哪些路徑被執行
  • 高 coverage 仍可能沒有有效 assertion
  • 低風險樣板與高風險規則不應等量看待
  • Mutation test 可檢查測試是否真的能抓到錯誤
  • 最重要的是風險是否有相對應的證據

Performance 與 Security Test

  • Load、stress、soak、benchmark 與 capacity test
  • 建立 baseline,再比較修改前後
  • SAST、DAST、dependency scan 與 secret scan
  • 權限、注入、資料外洩與 abuse case
  • 結果需要明確 threshold 與處置方式

CI 裡的 Quality Gate

build → lint → type check → unit test
      → integration test → scan → package
      → 必要時 deploy preview → E2E

哪些失敗要阻擋 merge,哪些只提出警告,需要明確規則。

一份測試結果要回答什麼?

  • 測了哪個版本、設定與環境?
  • 哪些案例通過、失敗或沒有執行?
  • 失敗是產品缺陷、環境問題還是測試不穩定?
  • 哪些風險尚未被覆蓋?
  • 目前證據是否足以 approve、merge 或 release?

看到 Agent 跑測試時

不要只看最後一行 passed。
要知道它跑的是 unit、integration、E2E 還是 acceptance,
使用什麼資料,以及沒測到哪些風險。