測驗:Vitest React 測試教學 – 為什麼選擇 Vitest?
共 5 題,點選答案後會立即顯示結果
1. Vitest 比 Jest 快的主要原因是什麼?
2. 在 Vite + React 專案中,測試 React 元件需要安裝哪個套件來模擬瀏覽器環境?
3. 在 vite.config.ts 中設定 globals: true 的作用是什麼?
4. Vitest 預設會將哪些檔案當成測試檔來執行?
5. 下列哪個 matcher 用於比較物件或陣列的深度相等?
expect(obj1).????(obj2)
一句話說明
Vitest 是專為 Vite 設計的測試框架,比 Jest 快 10 倍,設定更簡單。
為什麼要學 Vitest?
當你用 AI 產生 React + Vite 專案時,測試設定檔裡可能會看到 Vitest。這篇教你看懂:
- Vitest 是什麼?跟 Jest 有什麼不同?
- 怎麼安裝和設定?
- 怎麼跑第一個測試?
Vitest vs Jest:30 秒搞懂差異
| 比較項目 | Jest | Vitest |
|---|---|---|
| 速度 | 慢(冷啟動要等) | 快 10 倍以上 |
| 設定 | 需要額外設定 Babel/ts-jest | 共用 Vite 設定,開箱即用 |
| ESM 支援 | 要手動設定,常出問題 | 原生支援,不用設定 |
| Watch 模式 | 普通 | 超快(用 Vite 的 HMR) |
一句話總結:如果你用 Vite 建專案,選 Vitest 就對了。
為什麼 Vitest 比較快?
Jest 執行流程:
程式碼 → Babel 轉譯 → Jest 執行 → 結果
Vitest 執行流程:
程式碼 → Vite 直接執行(ESM 原生) → 結果
Vitest 省掉了轉譯步驟,所以快很多。
安裝與設定
最小安裝
# 進入你的 Vite + React 專案
npm install -D vitest jsdom @testing-library/react @testing-library/jest-dom
Code language: CSS (css)這些套件在幹嘛:
| 套件 | 用途 |
|---|---|
vitest |
測試框架本體 |
jsdom |
模擬瀏覽器環境(讓測試能跑 DOM) |
@testing-library/react |
用來 render React 元件 |
@testing-library/jest-dom |
提供 .toBeInTheDocument() 等好用的 matcher |
設定 vite.config.ts
打開 vite.config.ts,加入 test 設定:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
test: {
globals: true, // 可以直接用 describe, it, expect
environment: 'jsdom', // 模擬瀏覽器環境
setupFiles: './src/setupTests.ts', // 測試前要執行的檔案
},
})
Code language: JavaScript (javascript)逐行翻譯:
test: { // 測試相關設定
globals: true, // 不用 import { describe, it } 就能用
environment: 'jsdom', // 用 jsdom 模擬瀏覽器
setupFiles: './src/setupTests.ts', // 每次測試前先跑這個檔案
}
Code language: JavaScript (javascript)建立 setupTests.ts
建立 src/setupTests.ts:
import '@testing-library/jest-dom'
Code language: JavaScript (javascript)這行在幹嘛:引入 jest-dom 的 matcher,讓你可以用 .toBeInTheDocument() 這類語法。
加入 test script
在 package.json 加入:
{
"scripts": {
"test": "vitest",
"test:ui": "vitest --ui"
}
}
Code language: JSON / JSON with Comments (json)第一個測試:測試 Utility Function
先從最簡單的開始——測試一個純函式。
建立要測試的函式
建立 src/utils/math.ts:
export function add(a: number, b: number): number {
return a + b
}
Code language: JavaScript (javascript)撰寫測試
建立 src/utils/math.test.ts:
import { describe, it, expect } from 'vitest'
import { add } from './math'
describe('add', () => {
it('should add two numbers', () => {
expect(add(1, 2)).toBe(3)
})
})
Code language: JavaScript (javascript)逐行翻譯:
import { describe, it, expect } from 'vitest' // 引入測試工具
import { add } from './math' // 引入要測試的函式
describe('add', () => { // 定義一組測試,名稱是 'add'
it('should add two numbers', () => { // 定義單一測試案例
expect(add(1, 2)).toBe(3) // 預期 add(1, 2) 的結果是 3
})
})
Code language: JavaScript (javascript)執行測試
npm test
你會看到:
✓ src/utils/math.test.ts (1)
✓ add (1)
✓ should add two numbers
Test Files 1 passed (1)
Tests 1 passed (1)
常見變化
AI 產生的測試可能長這樣:
變化 1:不用 describe 直接寫 test
import { expect, test } from 'vitest'
import { add } from './math'
test('adds 1 + 2 to equal 3', () => {
expect(add(1, 2)).toBe(3)
})
Code language: JavaScript (javascript)翻譯:test 跟 it 一樣,只是換個名稱。不用 describe 包也可以跑。
變化 2:使用 globals(不用 import)
如果你設定了 globals: true,可以這樣寫:
// 不需要 import { describe, it, expect } from 'vitest'
import { add } from './math'
describe('add', () => {
it('should add two numbers', () => {
expect(add(1, 2)).toBe(3)
})
})
Code language: JavaScript (javascript)翻譯:設定 globals: true 後,describe、it、expect 變成全域可用。
變化 3:多個測試案例
describe('add', () => {
it('adds positive numbers', () => {
expect(add(1, 2)).toBe(3)
})
it('adds negative numbers', () => {
expect(add(-1, -2)).toBe(-3)
})
it('adds zero', () => {
expect(add(0, 5)).toBe(5)
})
})
Code language: PHP (php)翻譯:一個 describe 裡面可以有多個 it,測試不同情況。
常用 Matcher 翻譯表
| 你會看到 | 意思 |
|---|---|
expect(x).toBe(y) |
x 嚴格等於 y |
expect(x).toEqual(y) |
x 深度等於 y(用於物件/陣列) |
expect(x).toBeTruthy() |
x 是 truthy 值 |
expect(x).toBeFalsy() |
x 是 falsy 值 |
expect(x).toContain(y) |
x 包含 y |
expect(fn).toThrow() |
fn 會拋出錯誤 |
檔案命名規則
Vitest 預設會找這些檔案來跑測試:
✅ 會被當成測試檔
- math.test.ts
- math.spec.ts
- __tests__/math.ts
❌ 不會被當成測試檔
- math.ts
- mathTest.ts
記住:檔名要有 .test. 或 .spec. 或放在 tests 資料夾。
Vibe Coder 檢查點
看到 Vitest 設定時確認:
- [ ]
vite.config.ts有test區塊嗎? - [ ] 有設定
environment: 'jsdom'嗎?(測 React 需要) - [ ] 有建立
setupTests.ts嗎? - [ ]
package.json有"test": "vitest"script 嗎?
看到測試程式碼時確認:
- [ ] 檔名有
.test.或.spec.嗎? - [ ]
expect()後面的 matcher 看得懂嗎? - [ ] 測試描述清楚說明在測什麼嗎?
延伸:知道就好
這些進階功能遇到再查:
- Coverage 報告:
vitest --coverage看測試覆蓋率 - UI 模式:
vitest --ui會開一個漂亮的網頁介面 - Snapshot 測試:用
.toMatchSnapshot()比對輸出 - Mock 功能:
vi.fn()、vi.mock()模擬函式和模組
本篇重點整理
選 Vitest 的理由:
├── 速度快 10 倍(省掉 Babel 轉譯)
├── 設定簡單(共用 vite.config.ts)
└── ESM 原生支援(不用額外設定)
安裝四件套:
├── vitest(測試框架)
├── jsdom(模擬瀏覽器)
├── @testing-library/react(render 元件)
└── @testing-library/jest-dom(好用 matcher)
測試語法:
├── describe() → 定義一組測試
├── it() / test() → 定義單一測試
└── expect().toBe() → 斷言結果
Code language: CSS (css)下一篇預告
學會跑測試後,下一篇我們來測試 React 元件——用 render() 和 screen 找到畫面上的元素,驗證元件有沒有正確顯示。
進階測驗:Vitest React 測試教學 – 為什麼選擇 Vitest?
測驗目標:驗證你是否能在實際情境中應用所學。
共 5 題,包含情境題與錯誤診斷題。
共 5 題,包含情境題與錯誤診斷題。
1. 你剛用 Vite 建立了一個 React 專案,現在要加入測試功能。以下哪個安裝指令是正確且完整的? 情境題
2. 同事寫了以下測試檔案,但執行 npm test 後測試沒有被執行。問題出在哪裡? 錯誤診斷
// 檔案路徑:src/utils/mathTest.ts
import { add } from ‘./math’
describe(‘add’, () => {
it(‘should add two numbers’, () => {
expect(add(1, 2)).toBe(3)
})
})
3. 你正在設定 vite.config.ts,想要讓測試可以測試 React 元件的 DOM 操作。以下哪個設定是必要的? 情境題
export default defineConfig({
plugins: [react()],
test: {
// 這裡要加什麼?
},
})
4. 同事的測試出現以下錯誤訊息,最可能的原因是什麼? 錯誤診斷
TypeError: expect(…).toBeInTheDocument is not a function
5. 你需要測試一個函式,確認它回傳的物件內容正確。以下哪個寫法最適合? 情境題
function getUser() {
return { name: ‘Alice’, age: 25 }
}
// 測試要驗證回傳的物件是 { name: ‘Alice’, age: 25 }