bun-test について
bun-testは、Bun組み込みのテストランナーを設定し利用するためのスキルです。テスト構成、Jestからの移行、モック、カバレッジ設定、一般的なテスト手法を開発者向けに案内します。
主な機能
- 01Bunテストランナーの設定
- 02単体テストと結合テストの整理
- 03Jest互換のテストAPIの利用
- 04モックとスパイの設定
- 05カバレッジとウォッチモードの設定
活用シーン
- 01Bunプロジェクトのテスト環境構築
- 02Jestからのテスト移行
- 03API、非同期コード、データベース処理のテスト
- 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 テストの設定
Jest 互換の API を備え、実行速度が大幅に向上した(Jest より 3~10 倍高速)Bun 組み込みのテストランナーを設定します。
クイックリファレンス
詳しいパターンについては、以下を参照してください。
- 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 Test を設定する
プロジェクトのルートに 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 対応