Skip to content

테스트 러너는 다음 라이프사이클 훅을 지원합니다. 이는 테스트 픽스처 로드, 데이터 목킹 및 테스트 환경 구성에 유용합니다.

설명
beforeAll모든 테스트 전에 한 번 실행됩니다.
beforeEach각 테스트 전에 실행됩니다.
afterEach각 테스트 후에 실행됩니다.
afterAll모든 테스트 후에 한 번 실행됩니다.
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();
});

비동기 라이프사이클 훅

모든 라이프사이클 훅은 async 함수를 지원합니다.

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("File beforeAll"));
afterAll(() => console.log("File afterAll"));

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

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

    test("중첩 테스트", () => {
      console.log("테스트 실행");
    });
  });
});
txt
// 출력 순서:
// File beforeAll
// Outer beforeAll
// Inner beforeAll
// Outer beforeEach
// Inner beforeEach
// Test running
// Inner afterEach
// Outer afterEach
// Inner afterAll
// Outer afterAll
// File 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 편집