Skip to content

import Test from "/snippets/cli/test.mdx";

Bun 附帶一個快速、內置、與 Jest 兼容的測試運行器。測試使用 Bun 運行時執行,並支持以下功能。

  • TypeScript 和 JSX
  • 生命周期鉤子
  • 快照測試
  • UI 和 DOM 測試
  • 使用 --watch 的監視模式
  • 使用 --preload 的腳本預加載

NOTE

Bun 致力於與 Jest 兼容,但並非所有功能都已實現。要跟蹤兼容性,請參閱 [此跟蹤問題](https://github.com/oven-sh/bun/issues/1825)。

運行測試

bash
bun test

測試使用 JavaScript 或 TypeScript 編寫,采用類似 Jest 的 API。有關完整文檔,請參閱 編寫測試

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

test("2 + 2", () => {
  expect(2 + 2).toBe(4);
});

測試運行器會遞歸搜索工作目錄中符合以下模式的文件:

  • *.test.{js|jsx|ts|tsx}
  • *_test.{js|jsx|ts|tsx}
  • *.spec.{js|jsx|ts|tsx}
  • *_spec.{js|jsx|ts|tsx}

你可以通過向 bun test 傳遞額外的位置參數來過濾要運行的 測試文件。任何路徑與過濾器之一匹配的測試文件都將運行。通常,這些過濾器將是文件或目錄名稱;目前不支持 glob 模式。

bash
bun test <filter> <filter> ...

要按 測試名稱 過濾,請使用 -t/--test-name-pattern 標志。

sh
# 運行名稱中包含 "addition" 的所有測試或測試套件
bun test --test-name-pattern addition

要在測試運行器中運行特定文件,請確保路徑以 .// 開頭,以區別於過濾器名稱。

bash
bun test ./test/specific-file.test.ts

測試運行器在單個進程中運行所有測試。它加載所有 --preload 腳本(有關詳細信息,請參閱 生命周期),然後運行所有測試。如果測試失敗,測試運行器將以非零退出碼退出。

CI/CD 集成

bun test 支持各種 CI/CD 集成。

GitHub Actions

bun test 自動檢測是否在 GitHub Actions 內運行,並將 GitHub Actions 注解直接輸出到控制台。

除了在工作流中安裝 bun 並運行 bun test 外,不需要其他配置。

如何在 GitHub Actions 工作流中安裝 bun

要在 GitHub Actions 工作流中使用 bun test,請添加以下步驟:

yaml
jobs:
  build:
    name: build-app
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Install bun
        uses: oven-sh/setup-bun@v2
      - name: Install dependencies # 假設你的項目有依賴
        run: bun install # 如果你更喜歡,可以使用 npm/yarn/pnpm 代替
      - name: Run tests
        run: bun test

從這裡開始,你將獲得 GitHub Actions 注解。

JUnit XML 報告(GitLab 等)

要將 bun test 與 JUnit XML 報告器一起使用,可以將 --reporter=junit--reporter-outfile 結合使用。

sh
bun test --reporter=junit --reporter-outfile=./bun.xml

這將像往常一樣繼續輸出到 stdout/stderr,並在測試運行結束時將 JUnit XML 報告寫入給定路徑。

JUnit XML 是在 CI/CD 管道中報告測試結果的一種流行格式。

超時

使用 --timeout 標志指定 每個測試 的超時時間(以毫秒為單位)。如果測試超時,它將被標記為失敗。默認值為 5000

bash
# 默認值為 5000
bun test --timeout 20

並發測試執行

默認情況下,Bun 在每個測試文件中按順序運行所有測試。你可以啟用並發執行以並行運行異步測試,顯著加快具有獨立測試的測試套件。

--concurrent 標志

使用 --concurrent 標志在各自的文件內並發運行所有測試:

sh
bun test --concurrent

啟用此標志後,所有測試將並行運行,除非明確標記為 test.serial

--max-concurrency 標志

使用 --max-concurrency 標志控制同時運行的最大測試數:

sh
# 限制為 4 個並發測試
bun test --concurrent --max-concurrency 4

# 默認值:20
bun test --concurrent

這有助於在運行許多並發測試時防止資源耗盡。默認值為 20。

test.concurrent

標記單個測試以並發運行,即使未使用 --concurrent 標志:

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

// 這些測試彼此並行運行
test.concurrent("concurrent test 1", async () => {
  await fetch("/api/endpoint1");
  expect(true).toBe(true);
});

test.concurrent("concurrent test 2", async () => {
  await fetch("/api/endpoint2");
  expect(true).toBe(true);
});

// 此測試按順序運行
test("sequential test", () => {
  expect(1 + 1).toBe(2);
});

test.serial

強制測試按順序運行,即使啟用了 --concurrent 標志:

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

let sharedState = 0;

// 這些測試必須按順序運行
test.serial("first serial test", () => {
  sharedState = 1;
  expect(sharedState).toBe(1);
});

test.serial("second serial test", () => {
  // 依賴於上一個測試
  expect(sharedState).toBe(1);
  sharedState = 2;
});

# 如果啟用了 --concurrent,此測試可以並發運行
test("independent test", () => {
  expect(true).toBe(true);
});

// 鏈接測試限定符
test.failing.each([1, 2, 3])("chained qualifiers %d", input => {
  expect(input).toBe(0); // 此測試預計對每個輸入都失敗
});

重新運行測試

使用 --rerun-each 標志將每個測試運行多次。這對於檢測不穩定或非確定性測試失敗很有用。

sh
bun test --rerun-each 100

隨機化測試執行順序

使用 --randomize 標志以隨機順序運行測試。這有助於檢測依賴於共享狀態或執行順序的測試。

sh
bun test --randomize

使用 --randomize 時,隨機化使用的種子將顯示在測試摘要中:

sh
bun test --randomize
txt
# ... 測試輸出 ...
 --seed=12345
 2 pass
 8 fail
Ran 10 tests across 2 files. [50.00ms]

使用 --seed 的可重現隨機順序

使用 --seed 標志指定隨機化的種子。這允許你在調試依賴於順序的失敗時重現相同的測試順序。

sh
# 重現以前的隨機化運行
bun test --seed 123456

--seed 標志隱含 --randomize,因此你不需要同時指定兩者。使用相同的種子值將始終產生相同的測試執行順序,使調試由測試間依賴關系引起的間歇性失敗變得更加容易。

使用 --bail 退出

使用 --bail 標志在預定數量的測試失敗後提前中止測試運行。默認情況下,Bun 將運行所有測試並報告所有失敗,但有時在 CI 環境中,最好提前終止以減少 CPU 使用率。

sh
# 失敗 1 次後退出
bun test --bail

# 失敗 10 次後退出
bun test --bail=10

監視模式

bun run 類似,你可以將 --watch 標志傳遞給 bun test 以監視更改並重新運行測試。

bash
bun test --watch

生命周期鉤子

Bun 支持以下生命周期鉤子:

鉤子描述
beforeAll在所有測試之前運行一次。
beforeEach在每個測試之前運行。
afterEach在每個測試之後運行。
afterAll在所有測試之後運行一次。

這些鉤子可以在測試文件內定義,也可以在使用 --preload 標志預加載的單獨文件中定義。

sh
bun test --preload ./setup.ts

有關完整文檔,請參閱 測試 > 生命周期

模擬

使用 mock 函數創建模擬函數。

ts
import { test, expect, mock } from "bun:test";
const random = mock(() => Math.random());

test("random", () => {
  const val = random();
  expect(val).toBeGreaterThan(0);
  expect(random).toHaveBeenCalled();
  expect(random).toHaveBeenCalledTimes(1);
});

或者,你可以使用 jest.fn(),它的行為完全相同。

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

const random = mock(() => Math.random()); 
const random = jest.fn(() => Math.random()); 

有關完整文檔,請參閱 測試 > 模擬

快照測試

bun test 支持快照。

ts
// toMatchSnapshot 的示例用法
import { test, expect } from "bun:test";

test("snapshot", () => {
  expect({ a: 1 }).toMatchSnapshot();
});

要更新快照,請使用 --update-snapshots 標志。

sh
bun test --update-snapshots

有關完整文檔,請參閱 測試 > 快照

UI 和 DOM 測試

Bun 與流行的 UI 測試庫兼容:

有關完整文檔,請參閱 測試 > DOM 測試

性能

Bun 的測試運行器速度很快。

AI 代理集成

在使用 AI 編碼助手使用 Bun 的測試運行器時,你可以啟用更安靜的輸出以提高可讀性並減少上下文噪音。此功能最大限度地減少測試輸出的冗長,同時保留必要的失敗信息。

環境變量

設置以下任何環境變量以啟用 AI 友好的輸出:

  • CLAUDECODE=1 - 用於 Claude Code
  • REPL_ID=1 - 用於 Replit
  • AGENT=1 - 通用 AI 代理標志

行為

當檢測到 AI 代理環境時:

  • 僅詳細顯示測試失敗
  • 隱藏通過、跳過和待辦測試指示器
  • 匯總統計信息保持不變
bash
# 示例:為 Claude Code 啟用安靜輸出
CLAUDECODE=1 bun test

# 仍然顯示失敗和摘要,但隱藏冗長的通過測試輸出

此功能在 AI 輔助開發工作流中特別有用,減少的輸出冗長提高了上下文效率,同時保持了對測試失敗的可見性。

Bun學習網由www.bunjs.com.cn整理維護