运行时包管理器打包器测试运行器代码检查格式化指南参考博客反馈

测试配置

使用 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
# 覆盖率将被启用