bun-test

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Bun 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
undefined
bash
undefined

Verify Bun installation

验证Bun安装

bun --version
bun --version

Check if project exists

检查项目是否存在

ls -la package.json
undefined
ls -la package.json
undefined

2. 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
undefined
bash
undefined

Create 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
undefined
mkdir -p tests/{unit,integration,fixtures}

推荐结构:
project/ ├── src/ │ ├── utils.ts │ └── components/ ├── tests/ │ ├── unit/ # 单元测试 │ ├── integration/ # 集成测试 │ ├── fixtures/ # 测试数据 │ └── setup.ts # 全局设置 ├── package.json └── bunfig.toml # 测试配置
undefined

4. Configure Bun Test

4. 配置Bun测试

Create
bunfig.toml
in project root:
toml
[test]
在项目根目录创建
bunfig.toml
toml
[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
undefined
bail = false
undefined

5. Create Test Setup File

5. 创建测试设置文件

Create
tests/setup.ts
:
typescript
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.ts
typescript
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.ts
:
typescript
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.ts
typescript
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
undefined
bash
undefined

Run 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"
undefined
bun test --test-name-pattern="should handle"
undefined

Jest 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
undefined

Generate 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
undefined
bash
undefined

Run with debugger

带调试器运行

bun test --inspect
bun test --inspect

Verbose output

详细输出

bun test --verbose
bun test --verbose

Show all test results

显示所有测试结果

bun test --reporter=tap
undefined
bun test --reporter=tap
undefined

Performance

性能

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:
  1. Write tests: Add tests for critical business logic
  2. CI/CD: Configure tests to run in your pipeline
  3. Coverage: Set up coverage reporting
  4. Pre-commit: Add pre-commit hooks to run tests
  5. Documentation: Document testing patterns for the team
For detailed implementations, see the reference files linked above.
基础设置完成后:
  1. 编写测试:为关键业务逻辑添加测试
  2. CI/CD:在流水线中配置测试运行
  3. 覆盖率:设置覆盖率报告
  4. 提交前检查:添加提交前钩子运行测试
  5. 文档:为团队编写测试模式文档
如需详细实现,请查看上面链接的参考文件。