執行環境套件管理器打包器測試執行器程式碼檢查格式化指南參考部落格意見回饋

測試設定

使用 bunfig.toml 和命令列選項設定 bun test 行為

使用 bunfig.toml 和命令列選項設定 bun test。

設定檔

要在 bunfig.toml 中設定 bun test,請新增一個 [test] 部分:

bunfig.toml
[test]
# 選項寫在這裡

測試發現

root

root 選項設定 Bun 掃描測試的目錄,而不是專案根目錄。

bunfig.toml
[test]
root = "src"  # 只在 src 目錄內掃描測試

範例

bunfig.toml
[test]
# 只執行 src 目錄中的測試
root = "src"

# 在特定測試目錄中執行測試
root = "tests"

# 同時執行多個特定目錄中的測試(當前不支援 - 請改用 patterns)
# root = ["src", "lib"]  # 此語法不被支援

預載入指令碼

preload 選項會在測試執行前載入指令碼:

bunfig.toml
[test]
preload = ["./test-setup.ts", "./global-mocks.ts"]

這等同於命令列中使用 --preload:

terminal
bun test --preload ./test-setup.ts --preload ./global-mocks.ts

常見預載入用例

test-setup.ts
// 全域性測試設定
import { beforeAll, afterAll } from "bun:test";

beforeAll(() => {
  // 設定測試資料庫
  setupTestDatabase();
});

afterAll(() => {
  // 清理
  cleanupTestDatabase();
});
global-mocks.ts
// 全域性 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 識別的目錄時,可以使用此選項。

bunfig.toml
[test]
# 單個模式
pathIgnorePatterns = "vendor/**"

# 多個模式
pathIgnorePatterns = [
  "vendor/**",
  "submodules/**",
  "fixtures/**"
]

這等同於在命令列中使用 --path-ignore-patterns:

terminal
bun test --path-ignore-patterns 'vendor/**' --path-ignore-patterns 'fixtures/**'

Bun 會在掃描期間清理匹配模式的目錄,並且不會遍歷其內容,因此忽略大型目錄樹的開銷很低。

常見用例

bunfig.toml
[test]
pathIgnorePatterns = [
  # 帶有自己測試套件的 Git 子模組
  "submodules/**",

  # Vendored 相依
  "vendor/**",
  "third-party/**",

  # 看起來像測試但實際上不是的測試夾具
  "fixtures/**",
  "**/test-data/**",

  # 你想單獨執行的整合 / E2E 測試
  "**/integration/**",
  "e2e/**"
]

報告器

JUnit 報告器

在設定檔中直接設定 JUnit 報告器的輸出檔案路徑:

bunfig.toml
[test.reporter]
junit = "path/to/junit.xml"  # JUnit XML 報告的輸出路徑

這與命令列引數 --reporter=junit 和 --reporter-outfile 相輔相成:

terminal
# 等效的命令列用法
bun test --reporter=junit --reporter-outfile=./junit.xml

多重報告器

你可以同時使用多個報告器:

terminal
# 命令列方式
bun test --reporter=junit --reporter-outfile=./junit.xml

# 設定檔方式
bunfig.toml
[test.reporter]
junit = "./reports/junit.xml"

[test]
# 同時啟用覆蓋率報告
coverage = true
coverageReporter = ["text", "lcov"]

記憶體使用

smol 模式

為測試執行器開啟 --smol 的節省記憶體模式:

bunfig.toml
[test]
smol = true  # 在測試執行環境減少記憶體使用

該選項等同於命令列使用 --smol:

terminal
bun test --smol

smol 模式通過以下方式降低記憶體佔用:

  • 使用更小的 JavaScript 堆記憶體
  • 更積極地進行垃圾回收
  • 儘可能減少緩衝區大小

在記憶體受限的環境中使用它,例如 CI 執行器,或用於大型測試套件。

測試執行

concurrentTestGlob

啟用並行測試執行,執行匹配 glob 模式的測試檔案。

bunfig.toml
[test]
concurrentTestGlob = "**/concurrent-*.test.ts"  # 對匹配此模式的檔案並行執行

匹配此模式的測試檔案,其行為就像傳入了 --concurrent 標誌:這些檔案中的每個測試都會並行執行。你可以用它逐步將測試套件遷移到並行執行,也可以讓某一類測試(例如整合測試)並行執行,同時讓其餘測試保持順序執行。

--concurrent CLI 標誌會覆蓋此設定,無論 glob 模式如何,都會強制所有測試並行執行。

randomize

隨機執行測試,用於發現存在隱式相依的測試:

bunfig.toml
[test]
randomize = true

seed

指定用於生成可復現隨機順序的種子。需要設定 randomize = true:

bunfig.toml
[test]
randomize = true
seed = 2444615283

retry

所有測試的預設重試次數。Bun 會在測試失敗時,最多按此次數重試。每個測試的 { retry: N } 會覆蓋此值。預設為 0(不重試)。

bunfig.toml
[test]
retry = 3

--retry CLI 標誌會覆蓋此設定。

rerunEach

多次重新執行每個測試檔案,用於發現不穩定測試:

bunfig.toml
[test]
rerunEach = 3

覆蓋率選項

基礎覆蓋率設定

bunfig.toml
[test]
# 預設啟用覆蓋率
coverage = true

# 設定覆蓋率報告型別
coverageReporter = ["text", "lcov"]

# 覆蓋率輸出目錄
coverageDir = "./coverage"

避免測試檔案計入覆蓋率

從覆蓋率報告中排除匹配測試模式的檔案(例如 *.test.ts):

bunfig.toml
[test]
coverageSkipTestFiles = true  # 從覆蓋率報告中排除測試檔案

覆蓋率閾值

將覆蓋率閾值指定為單個數字,或指定為包含各指標閾值的物件:

bunfig.toml
[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 鍵,但目前不會強制執行該閾值。此檢查適用於任何覆蓋率報告器。

閾值範例

bunfig.toml
[test]
# 要求全面達到 90% 覆蓋率
coverageThreshold = 0.9

# 不同指標不同要求
coverageThreshold = {
  lines = 0.85,      # 85% line coverage
  functions = 0.90   # 90% function coverage
}

忽略路徑模式

使用 glob 模式排除特定檔案或檔案模式不計入覆蓋率報告:

bunfig.toml
[test]
# 單個模式
coveragePathIgnorePatterns = "**/*.spec.ts"

# 多個模式
coveragePathIgnorePatterns = [
  "**/*.spec.ts",
  "**/*.test.ts",
  "src/utils/**",
  "*.config.js",
  "generated/**",
  "vendor/**"
]

Bun 會將匹配任一模式的檔案排除在覆蓋率計算和報告之外。請參閱程式碼覆蓋率。

常見忽略模式

bunfig.toml
[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 可能會移動程式碼並重命名變數。此選項主要用於除錯覆蓋率問題。

bunfig.toml
[test]
coverageIgnoreSourcemaps = true  # 不使用 source map 進行覆蓋率分析

安裝設定繼承

bun test 會從 bunfig.toml 的 [install] 部分繼承網路和安裝設定(例如 registry、cafile、prefer 和 exact)。如果測試需要訪問私有登錄檔,或在執行期間觸發安裝,這一點就很重要。

bunfig.toml
[install]
# 這些設定會被 bun test 繼承
registry = "https://npm.company.com/"
exact = true
prefer = "offline"

[test]
# 測試專用設定
coverage = true

環境變數

使用 .env 檔案為測試設定環境變數,Bun 會自動從專案根目錄載入這些檔案。對於特定於測試的變數,建立一個 .env.test 檔案,bun test 會自動載入該檔案:

.env.test
NODE_ENV=test
DATABASE_URL=postgresql://localhost:5432/test_db
LOG_LEVEL=error

完整設定範例

展示可用測試設定選項的範例:

bunfig.toml
[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"

命令列覆蓋行為

命令列選項總是會覆蓋設定檔設定:

bunfig.toml
[test]
coverage = false
terminal
# 此命令列選項會覆蓋設定檔
bun test --coverage
# 覆蓋率將被啟用