認識測試與測試類型
什麼是測試
測試是一種驗證程式碼行為是否符合預期的方式。透過撰寫測試,我們可以更早發現錯誤、減少回歸風險、提高程式碼可維護性,並協助團隊理解功能需求。
💡 核心概念
不論何種測試,都是透過 確認「輸入 → 過程 → 輸出」正確性 ,讓我們更有信心地修改與擴充程式碼。
測試的原則
- 可重複:每次執行結果一致,不受環境與順序影響。
- 易理解:測試名稱與內容應說明測試目的。
- 小而聚焦:每個測試只驗證一個邏輯或功能單元。
- 獨立性:測試應彼此獨立,失敗能清楚指出問題點。
- 快速執行:能夠在開發流程中快速驗證結果。
認識測試類型
單元測試(Unit Test)
單元測試是針對「單一函式、模組或元件」進行測試,重點在於驗證其輸入與輸出是否正確,強調 isolation,通常會 mock 外部依賴(如 API、store)。
- 適用:工具函式、計算邏輯、單一元件(含 props、emit)、store、hook、純邏輯元件
- 特點:通常會 mock 外部依賴,以聚焦在測試點上
💸成本:
- 建置:低(可在專案初期設定一次測試框架)
- 撰寫:低至中(邏輯明確者容易寫,具副作用者需思考模擬)
👍優點:
- 快速執行,回饋即時
- 開發早期導入效果佳
- 問題定位精準
整合測試(Integration Test)
整合測試會驗證「多個模組或元件整合後」的行為與資料流是否能正常運作。它比單元測試更貼近實際使用情境,但也更耗時。
- 適用:頁面、元件與 store/router 的結合、複雜交互流程、資料加載流程
- 特點:通常不 mock 子元件 (或保留部分 mock),以模擬真實操作
💸成本:
- 建置:中(需安裝完整渲染測試工具與 mock)
- 撰寫:中至高(需處理多個元件交互與依賴)
👍優點:
- 接近真實情境,容易發現模組銜接的問題
- 相較 e2e 更快、維護性較高
E2E 測試(End-to-End Test)
E2E 測試模擬使用者的實際行為(如點擊、輸入、導頁),從 UI 開始到後端流程完整驗證,常用於測試整個流程是否如預期工作。
- 適用:登入流程、表單送出、購物流程等完整場景
- 特點: 較慢、維護成本高,重點放在 關鍵流程,通常需串聯真實的API,測試建置成本高
- 工具:Cypress、Playwright
💸成本:
- 建置:高(需有測試帳號、測試 API 或 mock server、CI 配置)
- 撰寫:高(需維護 selector、模擬真實使用者操作)
👍優點:
- 真實驗證使用者體驗
- 可作為關鍵流程驗收測試
其他測試類型
元件測試
針對「元件的互動、狀態變化、事件觸發」進行測試,屬於介於單元與整合之間的測試類型。常搭配 shallow rendering(淺層渲染)或 full rendering(完整渲染)。
快照測試(Snapshot Test)
將元件渲染結果存為快照,日後如有變更會比較差異,用來防止 UI 意外變動。但僅適合靜態、簡單元件,不可依賴快照當作主測試方式。
- 另有回歸測試、黑盒測試、白盒測試與灰盒測試,有興趣可再深入了解
測試撰寫流程
什麼是 3A
3A 是撰寫測試時常見的三步驟結構:
- Arrange(安排)– 設定初始狀態、建立資料、引入模組
- Act(執行)– 呼叫欲測試的函式或觸發操作
- Assert(驗證)– 檢查輸出或狀態是否符合預期
範例(Pseudocode):
// Arrange
const wrapper = mount(MyComponent) // 掛載被測元件
// Act
await wrapper.find('button').trigger('click') // 模擬被測元件裡的按鈕被點擊
// Assert
expect(wrapper.text()).toContain('Success') // 斷言被測元件裡應包含特定的字串常見的測試撰寫流程(適用於大部分測試類型)
- 分析需求與輸出行為:先思考元件/邏輯的輸入與輸出有哪些。
- 決定測試型別:這段邏輯是否為單一功能?是否涉及多個模組整合?是否屬於完整流程?
- 安排測試資料(Arrange):設定初始狀態、模擬資料或外部依賴。
- 執行測試操作(Act):觸發使用者操作或呼叫函式。
- 驗證預期結果(Assert):檢查畫面渲染、函式呼叫、資料狀態是否正確。
- 持續調整測試範圍與意圖:視需求變動,新增/修改/刪除測試。
測試策略模型比較與選擇
什麼是測試策略模型
測試策略模型是軟體開發中用來指導團隊如何有效配置測試資源的框架。它們幫助開發團隊回答一個關鍵問題:「我們應該寫多少測試?什麼類型的測試?」
主要作用:
- 幫助資源配置:幫助團隊決定在不同測試層級上投入多少時間和精力,避免盲目測試耗費太多成本或測試不足的問題。
- 成本效益平衡:不同類型的測試有不同的成本和效益。單元測試執行快速但覆蓋範圍有限;端到端測試覆蓋完整但執行緩慢且易出錯。策略模型幫助找到最佳平衡點。
- 團隊共識:為開發團隊提供共同的測試願景和目標,讓所有成員對測試策略有一致的理解。
實際應用:
- 制定測試計畫和測試標準
- 評估現有測試架構的健康程度,識別測試缺口或過度測試的區域
- 培訓新團隊成員理解測試最佳實踐
🔸 測試金字塔模型(Testing Pyramid)

▲
│ End-to-End Test(少量)
│ Integration Test(適量)
│ Unit Test(大量)
└──────────────- 優點:鼓勵大量低成本單元測試,減少高成本 E2E
- 問題:在現代應用中,整合層出現問題機率更高,金字塔可能測不到真正風險區
🏆 冠軍杯模型(Trophy Model)→ 我們採用!

▲
/ \ End-to-End Test(少量)
| | Integration Test(最多)
\ / Unit Test(適量)
/ \- 優點:更貼近實際開發情境,將重心放在「整合測試」驗證 UI 行為與資料整合
- 單元測試仍保留在工具、store 等區域,確保底層正確
- E2E 僅保留最關鍵路徑(如登入、送出流程)
✅ 我們的策略:以「整合測試」為主、「單元測試」輔助、「關鍵流程」用 E2E 驗證
重點:我們的專案如何進行測試?
認識 Vue 建議的測試方法
Vue 官方建議使用以下工具進行測試:
- Vitest:輕量快速的測試工具,可與 Vite 整合,適用於單元與整合測試
- Vue Test Utils:提供 mount、shallowMount 等測試元件 API
- Cypress / Playwright:適合做 e2e 測試,模擬實際使用者操作流程
✅ 測試 Vue hook(Composable)
對 Vue 的 useXXX() 類 hook 函式進行測試,流程與函式測試類似,重點在於輸入參數與回傳的反應式資料是否正確。
- 使用 @vue/reactivity 或 mount 測試具 DOM 操作的 hook
- 建議將 hook 分為:
- 純邏輯 hook(無副作用) → 使用 describe/it 直接測試
- 包含 DOM、watch、inject 等副作用的 hook → 用元件包裹測試
✅ 測試 .vue 元件的輸入與輸出
Vue 元件不像單純函式那樣「輸入參數 → 輸出結果」,我們需明確界定什麼是「輸入」與「輸出」:
元件的 輸入(Input)
- props(元件傳入參數)
- slots(插槽內容)
- provide/inject
- 使用的 store 狀態
- 外部環境(如 URL、localStorage、router 狀態)
- 使用的 hook(useXXX())
- 初始狀態(例如掛載時資料、API mock 回傳值)
元件的 輸出(Output)
- 結構與樣式渲染(HTML 結構是否正確、class 有無變化)
- DOM 互動(如按鈕點擊、輸入框輸入)
- 事件觸發(emit 的事件是否正確發出)
- 外部函式呼叫(如 API、第三方套件)
- 更新 store(如呼叫 store.action())
- 對 router 的操作(如導頁、query 更動)
- 操作子元件或觸發其事件
- 是否觸發特定 side effect(如 window.alert()、console.log())
🧠 思考方式:
- ✅ 只要會影響畫面或元件輸出結果的東西,就算是 輸入
- ✅ 只要會讓元件 對外產生影響 的行為,就算是 輸出
專案中各個區塊寫什麼測試?
✅ 需要單元測試的部分(聚焦小邏輯)
- 全域共用的工具函式(如格式化時間、處理數字)
- 各個 Pinia Store(state 改變、action 邏輯)
- 請求/回應攔截器(error handler、token 注入)
- 全域元件:Loading、Toast message、Modal 彈窗等
- 共用 hook / 頁面私有 hook(如 useXXX 邏輯組合)
✅ 需要整合測試的部分(涵蓋交互流程)
- 各個頁面(表單輸入、資料顯示、UI 行為)
- 跨元件互動(父子溝通、事件傳遞)
- API 整合流程(資料請求與渲染、錯誤提示)
✅ 可考慮進行 E2E 測試的部分(高風險區)
- 登入流程(含 token 管理)
- 建立/修改/刪除資料的流程(如送出表單)
- 導覽流程(導頁、登入後導向頁等)
學習資源
歡迎補充 !