bun-test
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBun Test Configuration
Bun 测试配置
Set up Bun's built-in test runner with Jest-compatible APIs and significantly faster execution (3-10x faster than Jest).
设置兼容Jest API的Bun内置测试运行器,执行速度显著提升(比Jest快3-10倍)。
Quick Reference
快速参考
For detailed patterns, see:
- Jest Migration: jest-migration.md - Complete Jest to Bun migration guide
- Mocking: mocking.md - Mock functions, spies, module mocking
- Examples: examples.md - Test patterns for APIs, databases, async code
如需详细模式,请查看:
- Jest迁移:jest-migration.md - 完整的Jest转Bun迁移指南
- 模拟:mocking.md - 模拟函数、间谍、模块模拟
- 示例:examples.md - API、数据库、异步代码的测试模式
Core Workflow
核心工作流程
1. Check Prerequisites
1. 检查前置条件
bash
undefinedbash
undefinedVerify Bun installation
验证Bun安装
bun --version
bun --version
Check if project exists
检查项目是否存在
ls -la package.json
undefinedls -la package.json
undefined2. Determine Testing Needs
2. 确定测试需求
Ask the user what type of testing they need:
- Unit Testing: Test individual functions and modules
- Integration Testing: Test component interactions
- API Testing: Test HTTP endpoints
- Snapshot Testing: Test output consistency
询问用户需要哪种类型的测试:
- 单元测试:测试独立函数和模块
- 集成测试:测试组件交互
- API测试:测试HTTP端点
- 快照测试:测试输出一致性
3. Create Test Directory Structure
3. 创建测试目录结构
bash
undefinedbash
undefinedCreate test directories
创建测试目录
mkdir -p tests/{unit,integration,fixtures}
Recommended structure:project/
├── src/
│ ├── utils.ts
│ └── components/
├── tests/
│ ├── unit/ # Unit tests
│ ├── integration/ # Integration tests
│ ├── fixtures/ # Test data
│ └── setup.ts # Global setup
├── package.json
└── bunfig.toml # Test configuration
undefinedmkdir -p tests/{unit,integration,fixtures}
推荐结构:project/
├── src/
│ ├── utils.ts
│ └── components/
├── tests/
│ ├── unit/ # 单元测试
│ ├── integration/ # 集成测试
│ ├── fixtures/ # 测试数据
│ └── setup.ts # 全局设置
├── package.json
└── bunfig.toml # 测试配置
undefined4. Configure Bun Test
4. 配置Bun测试
Create in project root:
bunfig.tomltoml
[test]在项目根目录创建:
bunfig.tomltoml
[test]Preload files before running tests
运行测试前预加载文件
preload = ["./tests/setup.ts"]
preload = ["./tests/setup.ts"]
Code coverage
代码覆盖率
coverage = true
coverageDir = "coverage"
coverageThreshold = 80
coverage = true
coverageDir = "coverage"
coverageThreshold = 80
Timeouts (in milliseconds)
超时时间(毫秒)
timeout = 5000
timeout = 5000
Bail after first failure
首次失败后终止测试
bail = false
undefinedbail = false
undefined5. Create Test Setup File
5. 创建测试设置文件
Create :
tests/setup.tstypescript
import { beforeAll, afterAll, beforeEach, afterEach } from "bun:test";
// Global test setup
beforeAll(() => {
console.log("🧪 Starting test suite");
process.env.NODE_ENV = "test";
});
afterAll(() => {
console.log("✅ Test suite complete");
});
// Reset mocks before each test
beforeEach(() => {
// Clear mock state
});
afterEach(() => {
// Cleanup after each test
});
// Global test utilities
globalThis.testHelpers = {
wait: (ms: number) => new Promise(resolve => setTimeout(resolve, ms)),
};创建:
tests/setup.tstypescript
import { beforeAll, afterAll, beforeEach, afterEach } from "bun:test";
// 全局测试设置
beforeAll(() => {
console.log("🧪 开始测试套件");
process.env.NODE_ENV = "test";
});
afterAll(() => {
console.log("✅ 测试套件完成");
});
// 每次测试前重置模拟
beforeEach(() => {
// 清除模拟状态
});
afterEach(() => {
// 每次测试后清理
});
// 全局测试工具
globalThis.testHelpers = {
wait: (ms: number) => new Promise(resolve => setTimeout(resolve, ms)),
};6. Write First Test
6. 编写第一个测试
Create :
tests/unit/example.test.tstypescript
import { describe, it, expect, test } from "bun:test";
// Simple test
test("addition works", () => {
expect(1 + 1).toBe(2);
});
// Describe blocks for organization
describe("Array utilities", () => {
it("should filter even numbers", () => {
const numbers = [1, 2, 3, 4, 5, 6];
const evens = numbers.filter(n => n % 2 === 0);
expect(evens).toEqual([2, 4, 6]);
expect(evens).toHaveLength(3);
});
});
// Async tests
describe("Async operations", () => {
it("should handle promises", async () => {
const result = await Promise.resolve(42);
expect(result).toBe(42);
});
});For more test examples (API testing, database testing, etc.), see examples.md.
创建:
tests/unit/example.test.tstypescript
import { describe, it, expect, test } from "bun:test";
// 简单测试
test("加法功能正常", () => {
expect(1 + 1).toBe(2);
});
// 使用Describe块组织测试
describe("数组工具", () => {
it("应该过滤偶数", () => {
const numbers = [1, 2, 3, 4, 5, 6];
const evens = numbers.filter(n => n % 2 === 0);
expect(evens).toEqual([2, 4, 6]);
expect(evens).toHaveLength(3);
});
});
// 异步测试
describe("异步操作", () => {
it("应该处理Promise", async () => {
const result = await Promise.resolve(42);
expect(result).toBe(42);
});
});如需更多测试示例(API测试、数据库测试等),请查看examples.md。
7. Add Mocking (If Needed)
7. 添加模拟(如有需要)
typescript
import { describe, it, expect, mock, spyOn } from "bun:test";
describe("Mock functions", () => {
it("should create mock functions", () => {
const mockFn = mock((x: number) => x * 2);
const result = mockFn(5);
expect(result).toBe(10);
expect(mockFn).toHaveBeenCalledTimes(1);
expect(mockFn).toHaveBeenCalledWith(5);
});
it("should spy on methods", () => {
const obj = {
method: (x: number) => x * 2,
};
const spy = spyOn(obj, "method");
obj.method(5);
expect(spy).toHaveBeenCalledWith(5);
expect(spy).toHaveReturnedWith(10);
});
});For advanced mocking patterns, see mocking.md.
typescript
import { describe, it, expect, mock, spyOn } from "bun:test";
describe("模拟函数", () => {
it("应该创建模拟函数", () => {
const mockFn = mock((x: number) => x * 2);
const result = mockFn(5);
expect(result).toBe(10);
expect(mockFn).toHaveBeenCalledTimes(1);
expect(mockFn).toHaveBeenCalledWith(5);
});
it("应该监视方法", () => {
const obj = {
method: (x: number) => x * 2,
};
const spy = spyOn(obj, "method");
obj.method(5);
expect(spy).toHaveBeenCalledWith(5);
expect(spy).toHaveReturnedWith(10);
});
});如需高级模拟模式,请查看mocking.md。
8. Update package.json
8. 更新package.json
Add test scripts:
json
{
"scripts": {
"test": "bun test",
"test:watch": "bun test --watch",
"test:coverage": "bun test --coverage",
"test:ui": "bun test --coverage --reporter=html"
}
}添加测试脚本:
json
{
"scripts": {
"test": "bun test",
"test:watch": "bun test --watch",
"test:coverage": "bun test --coverage",
"test:ui": "bun test --coverage --reporter=html"
}
}9. Run Tests
9. 运行测试
bash
undefinedbash
undefinedRun all tests
运行所有测试
bun test
bun test
Run specific file
运行指定文件
bun test tests/unit/utils.test.ts
bun test tests/unit/utils.test.ts
Watch mode
监听模式
bun test --watch
bun test --watch
With coverage
带覆盖率
bun test --coverage
bun test --coverage
Filter by name
按名称过滤
bun test --test-name-pattern="should handle"
undefinedbun test --test-name-pattern="should handle"
undefinedJest Migration
Jest迁移
If migrating from Jest, see jest-migration.md for:
- Import updates (→
@jest/globals)bun:test - Mock syntax changes (→
jest.fn())mock() - Configuration migration
- Compatibility notes
Key changes:
typescript
// Before (Jest)
import { describe, it, expect } from '@jest/globals';
const mockFn = jest.fn();
// After (Bun)
import { describe, it, expect, mock } from 'bun:test';
const mockFn = mock();如果从Jest迁移,请查看jest-migration.md了解:
- 导入更新(→
@jest/globals)bun:test - 模拟语法变化(→
jest.fn())mock() - 配置迁移
- 兼容性说明
主要变化:
typescript
// 之前(Jest)
import { describe, it, expect } from '@jest/globals';
const mockFn = jest.fn();
// 之后(Bun)
import { describe, it, expect, mock } from 'bun:test';
const mockFn = mock();Common Test Patterns
常见测试模式
Testing Functions
测试函数
typescript
import { test, expect } from "bun:test";
function add(a: number, b: number): number {
return a + b;
}
test("add function", () => {
expect(add(2, 3)).toBe(5);
expect(add(-1, 1)).toBe(0);
});typescript
import { test, expect } from "bun:test";
function add(a: number, b: number): number {
return a + b;
}
test("加法函数", () => {
expect(add(2, 3)).toBe(5);
expect(add(-1, 1)).toBe(0);
});Testing Errors
测试错误
typescript
test("should throw errors", () => {
const throwError = () => {
throw new Error("Something went wrong");
};
expect(throwError).toThrow("Something went wrong");
expect(throwError).toThrow(Error);
});
test("should reject promises", async () => {
const asyncReject = async () => {
throw new Error("Async error");
};
await expect(asyncReject()).rejects.toThrow("Async error");
});typescript
test("应该抛出错误", () => {
const throwError = () => {
throw new Error("出现问题");
};
expect(throwError).toThrow("出现问题");
expect(throwError).toThrow(Error);
});
test("应该拒绝Promise", async () => {
const asyncReject = async () => {
throw new Error("异步错误");
};
await expect(asyncReject()).rejects.toThrow("异步错误");
});Snapshot Testing
快照测试
typescript
test("should match snapshot", () => {
const data = {
id: 1,
name: "Test User",
email: "test@example.com",
};
expect(data).toMatchSnapshot();
});
test("should match inline snapshot", () => {
const config = { theme: "dark", language: "en" };
expect(config).toMatchInlineSnapshot(`
{
"theme": "dark",
"language": "en"
}
`);
});typescript
test("应该匹配快照", () => {
const data = {
id: 1,
name: "测试用户",
email: "test@example.com",
};
expect(data).toMatchSnapshot();
});
test("应该匹配内联快照", () => {
const config = { theme: "dark", language: "en" };
expect(config).toMatchInlineSnapshot(`
{
"theme": "dark",
"language": "en"
}
`);
});Matchers Reference
匹配器参考
Common matchers available:
typescript
// Equality
expect(value).toBe(expected); // ===
expect(value).toEqual(expected); // Deep equality
// Truthiness
expect(value).toBeTruthy();
expect(value).toBeFalsy();
expect(value).toBeDefined();
expect(value).toBeUndefined();
// Numbers
expect(number).toBeGreaterThan(3);
expect(number).toBeLessThan(5);
// Strings
expect(string).toMatch(/pattern/);
expect(string).toContain("substring");
// Arrays
expect(array).toContain(item);
expect(array).toHaveLength(3);
// Objects
expect(object).toHaveProperty("key");
expect(object).toMatchObject({ subset });
// Promises
await expect(promise).resolves.toBe(value);
await expect(promise).rejects.toThrow();
// Mock functions
expect(mockFn).toHaveBeenCalled();
expect(mockFn).toHaveBeenCalledTimes(3);
expect(mockFn).toHaveBeenCalledWith(arg1, arg2);可用的常见匹配器:
typescript
// 相等性
expect(value).toBe(expected); // ===
expect(value).toEqual(expected); // 深度相等
// 真值
expect(value).toBeTruthy();
expect(value).toBeFalsy();
expect(value).toBeDefined();
expect(value).toBeUndefined();
// 数字
expect(number).toBeGreaterThan(3);
expect(number).toBeLessThan(5);
// 字符串
expect(string).toMatch(/pattern/);
expect(string).toContain("子字符串");
// 数组
expect(array).toContain(item);
expect(array).toHaveLength(3);
// 对象
expect(object).toHaveProperty("key");
expect(object).toMatchObject({ subset });
// Promise
await expect(promise).resolves.toBe(value);
await expect(promise).rejects.toThrow();
// 模拟函数
expect(mockFn).toHaveBeenCalled();
expect(mockFn).toHaveBeenCalledTimes(3);
expect(mockFn).toHaveBeenCalledWith(arg1, arg2);Test Organization
测试组织
Setup and Teardown
设置与清理
typescript
import { beforeAll, afterAll, beforeEach, afterEach, describe, it } from "bun:test";
describe("User service", () => {
let db: Database;
beforeAll(async () => {
// Setup before all tests
db = await connectToDatabase();
});
afterAll(async () => {
// Cleanup after all tests
await db.close();
});
beforeEach(async () => {
// Reset before each test
await db.clear();
});
it("should create user", async () => {
const user = await db.users.create({ name: "Test" });
expect(user.id).toBeDefined();
});
});typescript
import { beforeAll, afterAll, beforeEach, afterEach, describe, it } from "bun:test";
describe("用户服务", () => {
let db: Database;
beforeAll(async () => {
// 所有测试前的设置
db = await connectToDatabase();
});
afterAll(async () => {
// 所有测试后的清理
await db.close();
});
beforeEach(async () => {
// 每次测试前重置
await db.clear();
});
it("应该创建用户", async () => {
const user = await db.users.create({ name: "测试" });
expect(user.id).toBeDefined();
});
});Coverage Configuration
覆盖率配置
View coverage report:
bash
undefined查看覆盖率报告:
bash
undefinedGenerate coverage
生成覆盖率
bun test --coverage
bun test --coverage
View HTML report
查看HTML报告
bun test --coverage --reporter=html
open coverage/index.html
Set coverage thresholds in `bunfig.toml`:
```toml
[test]
coverage = true
coverageThreshold = 80 # Fail if coverage < 80%bun test --coverage --reporter=html
open coverage/index.html
在`bunfig.toml`中设置覆盖率阈值:
```toml
[test]
coverage = true
coverageThreshold = 80 # 如果覆盖率<80%则测试失败Debugging Tests
调试测试
bash
undefinedbash
undefinedRun with debugger
带调试器运行
bun test --inspect
bun test --inspect
Verbose output
详细输出
bun test --verbose
bun test --verbose
Show all test results
显示所有测试结果
bun test --reporter=tap
undefinedbun test --reporter=tap
undefinedPerformance
性能
Bun test is significantly faster than Jest:
- Jest: ~15 seconds for 100 tests
- Bun: ~2 seconds for 100 tests
3-10x faster execution!
Bun测试比Jest快得多:
- Jest:100个测试约15秒
- Bun:100个测试约2秒
执行速度快3-10倍!
Completion Checklist
完成清单
- ✅ Test directory structure created
- ✅ bunfig.toml configured
- ✅ Test setup file created
- ✅ Example tests written
- ✅ Package.json scripts updated
- ✅ Tests run successfully
- ✅ Coverage configured (if needed)
- ✅ 已创建测试目录结构
- ✅ 已配置bunfig.toml
- ✅ 已创建测试设置文件
- ✅ 已编写示例测试
- ✅ 已更新Package.json脚本
- ✅ 测试运行成功
- ✅ 已配置覆盖率(如需)
Next Steps
后续步骤
After basic setup:
- Write tests: Add tests for critical business logic
- CI/CD: Configure tests to run in your pipeline
- Coverage: Set up coverage reporting
- Pre-commit: Add pre-commit hooks to run tests
- Documentation: Document testing patterns for the team
For detailed implementations, see the reference files linked above.
基础设置完成后:
- 编写测试:为关键业务逻辑添加测试
- CI/CD:在流水线中配置测试运行
- 覆盖率:设置覆盖率报告
- 提交前检查:添加提交前钩子运行测试
- 文档:为团队编写测试模式文档
如需详细实现,请查看上面链接的参考文件。