Skip to content

テストランナーは、次のライフサイクルフックをサポートしています。これは、テストフィクスチャの読み込み、データのモック、テスト環境の設定に役立ちます。

フック説明
beforeAllすべてのテストの前に 1 回実行します。
beforeEach各テストの前に実行します。
afterEach各テストの後に実行します。
afterAllすべてのテストの後に 1 回実行します。
onTestFinished単一のテストの完了後に実行します(すべての afterEach の後)。

テストごとのセットアップとティアダウン

beforeEachafterEach を使用して、テストごとのセットアップとティアダウンロジックを実行します。

ts
import { beforeEach, afterEach, test } from "bun:test";

beforeEach(() => {
  console.log("テストを実行中。");
});

afterEach(() => {
  console.log("テスト完了。");
});

// テスト...
test("テスト例", () => {
  // このテストは、前に beforeEach が実行され、後に afterEach が実行されます
});

スコープごとのセットアップとティアダウン

beforeAllafterAll を使用して、スコープごとのセットアップとティアダウンロジックを実行します。スコープは、フックが定義されている場所によって決定されます。

describe ブロックへのスコープ

フックを特定の describe ブロックにスコープするには。

ts
import { describe, beforeAll, afterAll, test } from "bun:test";

describe("テストグループ", () => {
  beforeAll(() => {
    // この describe ブロックのセットアップ
    console.log("テストグループのセットアップ");
  });

  afterAll(() => {
    // この describe ブロックのティアダウン
    console.log("テストグループのティアダウン");
  });

  test("テスト 1", () => {
    // テスト実装
  });

  test("テスト 2", () => {
    // テスト実装
  });
});

テストファイルへのスコープ

フックをテストファイル全体にスコープするには。

ts
import { describe, beforeAll, afterAll, test } from "bun:test";

beforeAll(() => {
  // ファイル全体のセットアップ
  console.log("テストファイルのセットアップ");
});

afterAll(() => {
  // ファイル全体のティアダウン
  console.log("テストファイルのティアダウン");
});

describe("テストグループ", () => {
  test("テスト 1", () => {
    // テスト実装
  });
});

onTestFinished

onTestFinished を使用して、単一のテストの完了後にコールバックを実行します。これは、すべての afterEach フックの後に実行されます。

ts
import { test, onTestFinished } from "bun:test";

test("テスト後にクリーンアップ", () => {
  onTestFinished(() => {
    // すべての afterEach フックの後に実行
    console.log("テスト完了");
  });
});

並行テストではサポートされていません。代わりに test.serial を使用してください。

グローバルセットアップとティアダウン

フックをマルチファイルのテスト実行全体にスコープするには、フックを別のファイルで定義します。

ts
import { beforeAll, afterAll } from "bun:test";

beforeAll(() => {
  // グローバルセットアップ
  console.log("グローバルテストセットアップ");
  // データベース接続の初期化、サーバーの起動など
});

afterAll(() => {
  // グローバルティアダウン
  console.log("グローバルテストティアダウン");
  // データベース接続のクローズ、サーバーの停止など
});

次に、--preload を使用して、テストファイルの前にセットアップスクリプトを実行します。

bash
bun test --preload ./setup.ts

テストを実行するたびに --preload と入力しないようにするには、bunfig.toml に追加できます。

toml
[test]
preload = ["./setup.ts"]

実用的な例

データベースセットアップ

ts
import { beforeAll, afterAll, beforeEach, afterEach } from "bun:test";
import { createConnection, closeConnection, clearDatabase } from "./db";

let connection;

beforeAll(async () => {
  // テストデータベースに接続
  connection = await createConnection({
    host: "localhost",
    database: "test_db",
  });
});

afterAll(async () => {
  // データベース接続をクローズ
  await closeConnection(connection);
});

beforeEach(async () => {
  // 各テストのためにクリーンなデータベースで開始
  await clearDatabase(connection);
});

API サーバーセットアップ

ts
import { beforeAll, afterAll } from "bun:test";
import { startServer, stopServer } from "./server";

let server;

beforeAll(async () => {
  // テストサーバーを起動
  server = await startServer({
    port: 3001,
    env: "test",
  });
});

afterAll(async () => {
  // テストサーバーを停止
  await stopServer(server);
});

モックセットアップ

ts
import { beforeEach, afterEach } from "bun:test";
import { mock } from "bun:test";

beforeEach(() => {
  // 一般的なモックを設定
  mock.module("./api-client", () => ({
    fetchUser: mock(() => Promise.resolve({ id: 1, name: "Test User" })),
    createUser: mock(() => Promise.resolve({ id: 2 })),
  }));
});

afterEach(() => {
  // 各テスト後にすべてのモックをクリア
  mock.restore();
});

非同期ライフサイクルフック

すべてのライフサイクルフックは非同期関数をサポートします。

ts
import { beforeAll, afterAll, test } from "bun:test";

beforeAll(async () => {
  // 非同期セットアップ
  await new Promise(resolve => setTimeout(resolve, 100));
  console.log("非同期セットアップ完了");
});

afterAll(async () => {
  // 非同期ティアダウン
  await new Promise(resolve => setTimeout(resolve, 100));
  console.log("非同期ティアダウン完了");
});

test("非同期テスト", async () => {
  // beforeAll の完了を待機します
  await expect(Promise.resolve("test")).resolves.toBe("test");
});

ネストされたフック

フックはネストでき、適切な順序で実行されます。

ts
import { describe, beforeAll, beforeEach, afterEach, afterAll, test } from "bun:test";

beforeAll(() => console.log("ファイル beforeAll"));
afterAll(() => console.log("ファイル afterAll"));

describe("外部 describe", () => {
  beforeAll(() => console.log("外部 beforeAll"));
  beforeEach(() => console.log("外部 beforeEach"));
  afterEach(() => console.log("外部 afterEach"));
  afterAll(() => console.log("外部 afterAll"));

  describe("内部 describe", () => {
    beforeAll(() => console.log("内部 beforeAll"));
    beforeEach(() => console.log("内部 beforeEach"));
    afterEach(() => console.log("内部 afterEach"));
    afterAll(() => console.log("内部 afterAll"));

    test("ネストされたテスト", () => {
      console.log("テスト実行中");
    });
  });
});
txt
// 出力順序:
// ファイル beforeAll
// 外部 beforeAll
// 内部 beforeAll
// 外部 beforeEach
// 内部 beforeEach
// テスト実行中
// 内部 afterEach
// 外部 afterEach
// 内部 afterAll
// 外部 afterAll
// ファイル afterAll

エラーハンドリング

ライフサイクルフックがエラーをスローすると、テスト実行に影響します。

ts
import { beforeAll, test } from "bun:test";

beforeAll(() => {
  // これがスローされると、このスコープのすべてのテストがスキップされます
  throw new Error("セットアップに失敗しました");
});

test("このテストはスキップされます", () => {
  // beforeAll が失敗したため、これは実行されません
});

より良いエラーハンドリングのために。

ts
import { beforeAll, test, expect } from "bun:test";

beforeAll(async () => {
  try {
    await setupDatabase();
  } catch (error) {
    console.error("データベースセットアップに失敗しました:", error);
    throw error; // テストスイートを失敗させるために再スロー
  }
});

ベストプラクティス

フックをシンプルに保つ

ts
// 良い:シンプルで焦点を絞ったセットアップ
beforeEach(() => {
  clearLocalStorage();
  resetMocks();
});

// 避ける:フック内の複雑なロジックはテストのデバッグを困難にします
beforeEach(async () => {
  // 複雑なロジックが多すぎるとテストのデバッグが困難になります
  const data = await fetchComplexData();
  await processData(data);
  await setupMultipleServices(data);
});

適切なスコープを使用する

ts
// 良い:共有リソースのファイルレベルセットアップ
beforeAll(async () => {
  await startTestServer();
});

// 良い:テスト固有の状態のテストレベルセットアップ
beforeEach(() => {
  user = createTestUser();
});

リソースをクリーンアップする

ts
import { afterAll, afterEach } from "bun:test";

afterEach(() => {
  // 各テスト後にクリーンアップ
  document.body.innerHTML = "";
  localStorage.clear();
});

afterAll(async () => {
  // 高価なリソースをクリーンアップ
  await closeDatabase();
  await stopServer();
});

Bun by www.bunjs.com.cn 編集