关于 bun-test
bun-test 是用于配置和使用 Bun 内置测试运行器的技能,面向开发者。内容涵盖测试组织、Jest 迁移、模拟、覆盖率配置和常见测试模式。
主要功能
- 01配置 Bun 测试运行器
- 02组织单元与集成测试
- 03使用兼容 Jest 的测试 API
- 04设置模拟函数与间谍
- 05配置覆盖率与监视模式
适用场景
- 01为 Bun 项目配置测试
- 02将测试从 Jest 迁移
- 03测试 API、异步代码或数据库交互
- 04生成覆盖率报告
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ daleseo/ bun-skills --skill bun-test安装后在 Claude Code 中输入/bun-test确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/examples.mdjest-migration.mdmocking.md详细介绍
Bun 测试配置
配置 Bun 内置测试运行器,使用兼容 Jest 的 API,并显著提升执行速度(比 Jest 快 3–10 倍)。
快速参考
如需了解详细模式,请参阅:
- Jest 迁移:jest-migration.md - 完整的 Jest 到 Bun 迁移指南
- 模拟:mocking.md - 模拟函数、间谍和模块
- 示例:examples.md - API、数据库和异步代码的测试模式
核心工作流
1. 检查先决条件
# Verify Bun installation
bun --version
# Check if project exists
ls -la package.json
2. 确定测试需求
询问用户需要哪种类型的测试:
- 单元测试:测试单个函数和模块
- 集成测试:测试组件交互
- API 测试:测试 HTTP 端点
- 快照测试:测试输出一致性
3. 创建测试目录结构
# Create test directories
mkdir -p tests/{unit,integration,fixtures}
推荐结构:
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
4. 配置 Bun 测试
在项目根目录中创建 bunfig.toml:
[test]
# Preload files before running tests
preload = ["./tests/setup.ts"]
# Code coverage
coverage = true
coverageDir = "coverage"
coverageThreshold = 80
# Timeouts (in milliseconds)
timeout = 5000
# Bail after first failure
bail = false
5. 创建测试设置文件
创建 tests/setup.ts:
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)),
};
6. 编写第一个测试
创建 tests/unit/example.test.ts:
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);
});
});
如需查看更多测试示例(API 测试、数据库测试等),请参阅 examples.md。
7. 添加模拟(如有需要)
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);
});
});
如需了解高级模拟模式,请参阅 mocking.md。
8. 更新 package.json
添加测试脚本:
{
"scripts": {
"test": "bun test",
"test:watch": "bun test --watch",
"test:coverage": "bun test --coverage",
"test:ui": "bun test --coverage --reporter=html"
}
}
9. 运行测试
# Run all tests
bun test
# Run specific file
bun test tests/unit/utils.test.ts
# Watch mode
bun test --watch
# With coverage
bun test --coverage
# Filter by name
bun test --test-name-pattern="should handle"
Jest 迁移
如果要从 Jest 迁移,请参阅 jest-migration.md,了解:
- 导入更新(
@jest/globals→bun:test) - 模拟语法变更(
jest.fn()→mock()) - 配置迁移
- 兼容性说明
主要变更:
// 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();
常见测试模式
测试函数
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);
});
测试错误
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");
});
快照测试
test("should match snapshot", () => {
const data = {
id: 1,
name: "Test User",
email: "[email protected]",
};
expect(data).toMatchSnapshot();
});
test("should match inline snapshot", () => {
const config = { theme: "dark", language: "en" };
expect(config).toMatchInlineSnapshot(`
{
"theme": "dark",
"language": "en"
}
`);
});
匹配器参考
常见的可用匹配器:
// 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);
测试组织
设置和清理
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();
});
});
覆盖率配置
查看覆盖率报告:
# Generate coverage
bun test --coverage
# View HTML report
bun test --coverage --reporter=html
open coverage/index.html
在 bunfig.toml 中设置覆盖率阈值:
[test]
coverage = true
coverageThreshold = 80 # Fail if coverage < 80%
调试测试
# Run with debugger
bun test --inspect
# Verbose output
bun test --verbose
# Show all test results
bun test --reporter=tap
性能
Bun 测试的速度显著快于 Jest:
- Jest:100 个测试约需 15 秒
- Bun:100 个测试约需 2 秒
执行速度快 3–10 倍!
完成检查清单
- ✅ 已创建测试目录结构
- ✅ 已配置 bunfig.toml
- ✅ 已创建测试设置文件
- ✅ 已编写示例测试
- ✅ 已更新 package.json 脚本
- ✅ 测试运行成功
- ✅ 已配置覆盖率(如有需要)
后续步骤
完成基本设置后:
- 编写测试:为关键业务逻辑添加测试
- CI/CD:配置测试在流水线中运行
- 覆盖率:设置覆盖率报告
- 提交前检查:添加提交前钩子以运行测试
- 文档:为团队记录测试模式
如需了解详细实现,请参阅上方链接的参考文件。
评论
支持 Markdown