使用從內建 bun:test
模組匯入的類似 Jest 的 API 定義測試。長期而言,Bun 的目標是完全相容於 Jest;目前,僅支援有限的集合的 expect
匹配器。
基本用法
定義簡單測試
import { expect, test } from "bun:test";
test("2 + 2", () => {
expect(2 + 2).toBe(4);
});
Jest 風格的全域變數
可以使用 describe
將測試分組到套件中。
import { expect, test, describe } from "bun:test";
describe("arithmetic", () => {
test("2 + 2", () => {
expect(2 + 2).toBe(4);
});
test("2 * 2", () => {
expect(2 * 2).toBe(4);
});
});
測試可以是 async
。
import { expect, test } from "bun:test";
test("2 * 2", async () => {
const result = await Promise.resolve(2 * 2);
expect(result).toEqual(4);
});
或者,使用 done
回呼來發出完成訊號。如果您在測試定義中包含 done
回呼作為參數,必須 呼叫它,否則測試將會掛起。
import { expect, test } from "bun:test";
test("2 * 2", done => {
Promise.resolve(2 * 2).then(result => {
expect(result).toEqual(4);
done();
});
});
逾時
您可以選擇性地指定每個測試的逾時時間(以毫秒為單位),方法是將數字作為 test
的第三個參數傳遞。
import { test } from "bun:test";
test("wat", async () => {
const data = await slowOperation();
expect(data).toBe(42);
}, 500); // test must run in <500ms
在 bun:test
中,測試逾時會拋出無法捕捉的例外,以強制停止測試執行並使其失敗。我們也會終止在測試中產生的任何子程序,以避免在背景中留下殭屍程序。
🧟 殭屍程序終結器
當測試逾時,且透過 Bun.spawn
、Bun.spawnSync
或 node:child_process
在測試中產生的程序未被終止時,它們將會被自動終止,並在主控台中記錄訊息。
test.skip
使用 test.skip
跳過個別測試。這些測試將不會執行。
import { expect, test } from "bun:test";
test.skip("wat", () => {
// TODO: fix this
expect(0.1 + 0.2).toEqual(0.3);
});
test.todo
使用 test.todo
將測試標記為待辦事項。這些測試將不會執行。
import { expect, test } from "bun:test";
test.todo("fix this", () => {
myTestFunction();
});
若要執行待辦測試並找出任何通過的測試,請使用 bun test --todo
。
bun test --todo
my.test.ts:
✗ unimplemented feature
^ this test is marked as todo but passes. Remove `.todo` or check that test is correct.
0 pass
1 fail
1 expect() calls
使用此標記時,失敗的待辦測試不會導致錯誤,但通過的待辦測試將被標記為失敗,以便您可以移除待辦標記或 修正測試。
test.only
若要執行特定的測試或測試套件,請使用 test.only()
或 describe.only()
。一旦宣告,執行 bun test --only
將只會執行標記為 .only()
的測試/套件。在宣告了 test.only()
的情況下,不使用 --only
選項執行 bun test
將會執行給定套件中的所有測試,直到 遇到 .only()
的測試為止。describe.only()
在這兩種執行情境下的運作方式相同。
import { test, describe } from "bun:test";
test("test #1", () => {
// does not run
});
test.only("test #2", () => {
// runs
});
describe.only("only", () => {
test("test #3", () => {
// runs
});
});
以下命令將僅執行測試 #2 和 #3。
bun test --only
以下命令將僅執行測試 #1、#2 和 #3。
bun test
test.if
若要有條件地執行測試,請使用 test.if()
。如果條件為真值,則測試將會執行。這對於僅應在特定架構或作業系統上執行的測試特別有用。
test.if(Math.random() > 0.5)("runs half the time", () => {
// ...
});
const macOS = process.arch === "darwin";
test.if(macOS)("runs on macOS", () => {
// runs if macOS
});
test.skipIf
若要改為根據某些條件跳過測試,請使用 test.skipIf()
或 describe.skipIf()
。
const macOS = process.arch === "darwin";
test.skipIf(macOS)("runs on non-macOS", () => {
// runs if *not* macOS
});
test.todoIf
如果改為想要將測試標記為 TODO,請使用 test.todoIf()
或 describe.todoIf()
。仔細選擇 skipIf
或 todoIf
可以區分例如「在此目標上無效」和「已計劃但尚未實作」的意圖。
const macOS = process.arch === "darwin";
// TODO: we've only implemented this for Linux so far.
test.todoIf(macOS)("runs on posix", () => {
// runs if *not* macOS
});
test.each
若要為測試表格中的多個案例傳回函式,請使用 test.each
。
const cases = [
[1, 2, 3],
[3, 4, 5],
];
test.each(cases)("%p + %p should be %p", (a, b, expected) => {
// runs once for each test case provided
});
有多種選項可用於格式化案例標籤,具體取決於其類型。
%p | 美化格式 |
%s | 字串 |
%d | 數字 |
%i | 整數 |
%f | 浮點數 |
%j | JSON |
%o | 物件 |
%# | 測試案例的索引 |
%% | 單個百分比符號 (% ) |
Matchers
Bun 實作了以下 Matchers。完整的 Jest 相容性正在路線圖上;在此處追蹤進度 here。