mcpField
B
bun-test

bun-test

github.com/daleseoテスト・品質4227 回インストール40 週間前に更新
リポジトリ

bun-test について

bun-testは、Bun組み込みのテストランナーを設定し利用するためのスキルです。テスト構成、Jestからの移行、モック、カバレッジ設定、一般的なテスト手法を開発者向けに案内します。

主な機能

  1. 01Bunテストランナーの設定
  2. 02単体テストと結合テストの整理
  3. 03Jest互換のテストAPIの利用
  4. 04モックとスパイの設定
  5. 05カバレッジとウォッチモードの設定

活用シーン

  1. 01Bunプロジェクトのテスト環境構築
  2. 02Jestからのテスト移行
  3. 03API、非同期コード、データベース処理のテスト
  4. 04カバレッジレポートの生成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/daleseo/bun-skills --skill bun-test

インストール後、Claude Code で/bun-testを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
examples.md
jest-migration.md
mocking.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 のスクリプトを更新済み
  • ✅ テストが正常に実行される
  • ✅ カバレッジを設定済み(必要な場合)

次のステップ

基本的な設定の後は、以下を行います。

  1. テストを作成する:重要なビジネスロジックのテストを追加します
  2. CI/CD:パイプラインでテストが実行されるように設定します
  3. カバレッジ:カバレッジレポートを設定します
  4. コミット前チェック:テストを実行するコミット前フックを追加します
  5. ドキュメント:チーム向けにテストパターンを文書化します

詳しい実装については、上記のリンク先のリファレンスファイルを参照してください。

コメント