測試設定
使用 bunfig.toml 和命令列選項設定 bun test 行為
使用 bunfig.toml 和命令列選項設定 bun test。
設定檔
要在 bunfig.toml 中設定 bun test,請新增一個 [test] 部分:
[test]
# 選項寫在這裡
測試發現
root
root 選項設定 Bun 掃描測試的目錄,而不是專案根目錄。
[test]
root = "src" # 只在 src 目錄內掃描測試
範例
[test]
# 只執行 src 目錄中的測試
root = "src"
# 在特定測試目錄中執行測試
root = "tests"
# 同時執行多個特定目錄中的測試(當前不支援 - 請改用 patterns)
# root = ["src", "lib"] # 此語法不被支援
預載入指令碼
preload 選項會在測試執行前載入指令碼:
[test]
preload = ["./test-setup.ts", "./global-mocks.ts"]
這等同於命令列中使用 --preload:
bun test --preload ./test-setup.ts --preload ./global-mocks.ts
常見預載入用例
// 全域性測試設定
import { beforeAll, afterAll } from "bun:test";
beforeAll(() => {
// 設定測試資料庫
setupTestDatabase();
});
afterAll(() => {
// 清理
cleanupTestDatabase();
});
// 全域性 Mock
import { mock } from "bun:test";
// Mock 環境變數
process.env.NODE_ENV = "test";
process.env.API_URL = "http://localhost:3001";
// Mock 外部相依
mock.module("./external-api", () => ({
fetchData: mock(() => Promise.resolve({ data: "test" })),
}));
路徑忽略模式
pathIgnorePatterns 使用 glob 模式,將檔案和目錄完全排除在測試發現範圍之外。與僅影響覆蓋率報告的 coveragePathIgnorePatterns 不同,pathIgnorePatterns 會阻止 Bun 發現匹配的路徑,並將其作為測試執行。
當專案包含子模組、第三方託管程式碼或其他包含 *.test.ts 檔案、但不希望被 bun test 識別的目錄時,可以使用此選項。
[test]
# 單個模式
pathIgnorePatterns = "vendor/**"
# 多個模式
pathIgnorePatterns = [
"vendor/**",
"submodules/**",
"fixtures/**"
]
這等同於在命令列中使用 --path-ignore-patterns:
bun test --path-ignore-patterns 'vendor/**' --path-ignore-patterns 'fixtures/**'
Bun 會在掃描期間清理匹配模式的目錄,並且不會遍歷其內容,因此忽略大型目錄樹的開銷很低。
常見用例
[test]
pathIgnorePatterns = [
# 帶有自己測試套件的 Git 子模組
"submodules/**",
# Vendored 相依
"vendor/**",
"third-party/**",
# 看起來像測試但實際上不是的測試夾具
"fixtures/**",
"**/test-data/**",
# 你想單獨執行的整合 / E2E 測試
"**/integration/**",
"e2e/**"
]
報告器
JUnit 報告器
在設定檔中直接設定 JUnit 報告器的輸出檔案路徑:
[test.reporter]
junit = "path/to/junit.xml" # JUnit XML 報告的輸出路徑
這與命令列引數 --reporter=junit 和 --reporter-outfile 相輔相成:
# 等效的命令列用法
bun test --reporter=junit --reporter-outfile=./junit.xml
多重報告器
你可以同時使用多個報告器:
# 命令列方式
bun test --reporter=junit --reporter-outfile=./junit.xml
# 設定檔方式
[test.reporter]
junit = "./reports/junit.xml"
[test]
# 同時啟用覆蓋率報告
coverage = true
coverageReporter = ["text", "lcov"]
記憶體使用
smol 模式
為測試執行器開啟 --smol 的節省記憶體模式:
[test]
smol = true # 在測試執行環境減少記憶體使用
該選項等同於命令列使用 --smol:
bun test --smol
smol 模式通過以下方式降低記憶體佔用:
- 使用更小的 JavaScript 堆記憶體
- 更積極地進行垃圾回收
- 儘可能減少緩衝區大小
在記憶體受限的環境中使用它,例如 CI 執行器,或用於大型測試套件。
測試執行
concurrentTestGlob
啟用並行測試執行,執行匹配 glob 模式的測試檔案。
[test]
concurrentTestGlob = "**/concurrent-*.test.ts" # 對匹配此模式的檔案並行執行
匹配此模式的測試檔案,其行為就像傳入了 --concurrent 標誌:這些檔案中的每個測試都會並行執行。你可以用它逐步將測試套件遷移到並行執行,也可以讓某一類測試(例如整合測試)並行執行,同時讓其餘測試保持順序執行。
--concurrent CLI 標誌會覆蓋此設定,無論 glob 模式如何,都會強制所有測試並行執行。
randomize
隨機執行測試,用於發現存在隱式相依的測試:
[test]
randomize = true
seed
指定用於生成可復現隨機順序的種子。需要設定 randomize = true:
[test]
randomize = true
seed = 2444615283
retry
所有測試的預設重試次數。Bun 會在測試失敗時,最多按此次數重試。每個測試的 { retry: N } 會覆蓋此值。預設為 0(不重試)。
[test]
retry = 3
--retry CLI 標誌會覆蓋此設定。
rerunEach
多次重新執行每個測試檔案,用於發現不穩定測試:
[test]
rerunEach = 3
覆蓋率選項
基礎覆蓋率設定
[test]
# 預設啟用覆蓋率
coverage = true
# 設定覆蓋率報告型別
coverageReporter = ["text", "lcov"]
# 覆蓋率輸出目錄
coverageDir = "./coverage"
避免測試檔案計入覆蓋率
從覆蓋率報告中排除匹配測試模式的檔案(例如 *.test.ts):
[test]
coverageSkipTestFiles = true # 從覆蓋率報告中排除測試檔案
覆蓋率閾值
將覆蓋率閾值指定為單個數字,或指定為包含各指標閾值的物件:
[test]
# Simple threshold - applies to lines and functions
coverageThreshold = 0.8
# Detailed thresholds
coverageThreshold = { lines = 0.9, functions = 0.8 }
設定閾值後,當啟用了覆蓋率且任何檔案的行覆蓋率或函式覆蓋率低於該閾值時,bun test 會以程式碼 1 退出。Bun 接受 statements 鍵,但目前不會強制執行該閾值。此檢查適用於任何覆蓋率報告器。
閾值範例
[test]
# 要求全面達到 90% 覆蓋率
coverageThreshold = 0.9
# 不同指標不同要求
coverageThreshold = {
lines = 0.85, # 85% line coverage
functions = 0.90 # 90% function coverage
}
忽略路徑模式
使用 glob 模式排除特定檔案或檔案模式不計入覆蓋率報告:
[test]
# 單個模式
coveragePathIgnorePatterns = "**/*.spec.ts"
# 多個模式
coveragePathIgnorePatterns = [
"**/*.spec.ts",
"**/*.test.ts",
"src/utils/**",
"*.config.js",
"generated/**",
"vendor/**"
]
Bun 會將匹配任一模式的檔案排除在覆蓋率計算和報告之外。請參閱程式碼覆蓋率。
常見忽略模式
[test]
coveragePathIgnorePatterns = [
# 測試檔案
"**/*.test.ts",
"**/*.spec.ts",
"**/*.e2e.ts",
# 設定檔
"*.config.js",
"*.config.ts",
"webpack.config.*",
"vite.config.*",
# 建置產物
"dist/**",
"build/**",
".next/**",
# 生成程式碼
"generated/**",
"**/*.generated.ts",
# 第三方庫
"vendor/**",
"third-party/**",
# 不需要測試的工具檔案
"src/utils/constants.ts",
"src/types/**"
]
Source Map 處理
Bun 會轉譯每個檔案,因此覆蓋率結果會在報告前經過 sourcemap 處理。coverageIgnoreSourcemaps 會選擇退出此處理,但這會導致結果難以理解:在轉譯期間,Bun 可能會移動程式碼並重命名變數。此選項主要用於除錯覆蓋率問題。
[test]
coverageIgnoreSourcemaps = true # 不使用 source map 進行覆蓋率分析
安裝設定繼承
bun test 會從 bunfig.toml 的 [install] 部分繼承網路和安裝設定(例如 registry、cafile、prefer 和 exact)。如果測試需要訪問私有登錄檔,或在執行期間觸發安裝,這一點就很重要。
[install]
# 這些設定會被 bun test 繼承
registry = "https://npm.company.com/"
exact = true
prefer = "offline"
[test]
# 測試專用設定
coverage = true
環境變數
使用 .env 檔案為測試設定環境變數,Bun 會自動從專案根目錄載入這些檔案。對於特定於測試的變數,建立一個 .env.test 檔案,bun test 會自動載入該檔案:
NODE_ENV=test
DATABASE_URL=postgresql://localhost:5432/test_db
LOG_LEVEL=error
完整設定範例
展示可用測試設定選項的範例:
[install]
# 測試繼承的安裝設定
registry = "https://registry.npmjs.org/"
exact = true
[test]
# 測試發現
root = "src"
preload = ["./test-setup.ts", "./global-mocks.ts"]
pathIgnorePatterns = ["vendor/**", "submodules/**"]
# 執行設定
smol = true
# 覆蓋率設定
coverage = true
coverageReporter = ["text", "lcov"]
coverageDir = "./coverage"
coverageThreshold = { lines = 0.85, functions = 0.90 }
coverageSkipTestFiles = true
coveragePathIgnorePatterns = [
"**/*.spec.ts",
"src/utils/**",
"*.config.js",
"generated/**"
]
# 高階覆蓋率設定
coverageIgnoreSourcemaps = false
# 報告器設定
[test.reporter]
junit = "./reports/junit.xml"
命令列覆蓋行為
命令列選項總是會覆蓋設定檔設定:
[test]
coverage = false
# 此命令列選項會覆蓋設定檔
bun test --coverage
# 覆蓋率將被啟用