【Vitest React 測試教學】#01 為什麼選擇 Vitest?從 Jest 無痛轉移

測驗:Vitest React 測試教學 – 為什麼選擇 Vitest?

共 5 題,點選答案後會立即顯示結果

1. Vitest 比 Jest 快的主要原因是什麼?

  • A. Vitest 使用更好的演算法
  • B. Vitest 省掉了 Babel 轉譯步驟,直接使用 ESM 原生執行
  • C. Vitest 只執行部分測試
  • D. Vitest 使用多執行緒平行處理

2. 在 Vite + React 專案中,測試 React 元件需要安裝哪個套件來模擬瀏覽器環境?

  • A. @testing-library/react
  • B. @testing-library/jest-dom
  • C. jsdom
  • D. vitest

3. 在 vite.config.ts 中設定 globals: true 的作用是什麼?

  • A. 讓 describe、it、expect 變成全域可用,不需要 import
  • B. 讓測試檔案可以存取全域變數
  • C. 啟用全域的 Mock 功能
  • D. 讓測試結果輸出到全域日誌

4. Vitest 預設會將哪些檔案當成測試檔來執行?

  • A. 所有 .ts 檔案
  • B. 檔名包含 .test. 或 .spec. 的檔案,以及 __tests__ 資料夾內的檔案
  • C. 只有 __tests__ 資料夾內的檔案
  • D. 所有 Test 結尾的檔案,如 mathTest.ts

5. 下列哪個 matcher 用於比較物件或陣列的深度相等?

expect(obj1).????(obj2)
  • A. toBe()
  • B. toEqual()
  • C. toContain()
  • D. toBeTruthy()

一句話說明

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)

翻譯testit 一樣,只是換個名稱。不用 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 後,describeitexpect 變成全域可用。

變化 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.tstest 區塊嗎?
  • [ ] 有設定 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 題,包含情境題與錯誤診斷題。

1. 你剛用 Vite 建立了一個 React 專案,現在要加入測試功能。以下哪個安裝指令是正確且完整的? 情境題

  • A. npm install vitest
  • B. npm install -D vitest jsdom
  • C. npm install -D vitest jsdom @testing-library/react @testing-library/jest-dom
  • D. npm install -D jest @testing-library/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) }) })
  • A. 缺少 import { describe, it, expect } from 'vitest'
  • B. 檔案命名錯誤,應該是 math.test.ts 而不是 mathTest.ts
  • C. 沒有設定 setupFiles
  • D. 缺少 export 關鍵字

3. 你正在設定 vite.config.ts,想要讓測試可以測試 React 元件的 DOM 操作。以下哪個設定是必要的? 情境題

export default defineConfig({ plugins: [react()], test: { // 這裡要加什麼? }, })
  • A. globals: true
  • B. environment: 'jsdom'
  • C. coverage: true
  • D. watch: true

4. 同事的測試出現以下錯誤訊息,最可能的原因是什麼? 錯誤診斷

TypeError: expect(…).toBeInTheDocument is not a function
  • A. 沒有安裝 vitest
  • B. 沒有設定 environment: 'jsdom'
  • C. 沒有在 setupTests.ts 中引入 @testing-library/jest-dom
  • D. 沒有安裝 @testing-library/react

5. 你需要測試一個函式,確認它回傳的物件內容正確。以下哪個寫法最適合? 情境題

function getUser() { return { name: ‘Alice’, age: 25 } } // 測試要驗證回傳的物件是 { name: ‘Alice’, age: 25 }
  • A. expect(getUser()).toBe({ name: 'Alice', age: 25 })
  • B. expect(getUser()).toEqual({ name: 'Alice', age: 25 })
  • C. expect(getUser()).toBeTruthy()
  • D. expect(getUser()).toContain({ name: 'Alice' })

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *