本指南演示如何使用 concurrentTestGlob 選項根據文件命名模式選擇性地並發運行測試。
項目結構
sh
my-project/
├── bunfig.toml
├── tests/
│ ├── unit/
│ │ ├── math.test.ts # 順序執行
│ │ └── utils.test.ts # 順序執行
│ └── integration/
│ ├── concurrent-api.test.ts # 並發執行
│ └── concurrent-database.test.ts # 並發執行配置
配置你的 bunfig.toml 以並發運行帶有 "concurrent-" 前綴的測試文件:
toml
[test]
# 並發運行所有帶有 "concurrent-" 前綴的測試文件
concurrentTestGlob = "**/concurrent-*.test.ts"測試文件
單元測試(順序執行)
當測試共享狀態或有特定順序要求時,順序執行測試是好的選擇:
ts
import { test, expect } from "bun:test";
// 這些測試默認順序執行
let sharedState = 0;
test("加法", () => {
sharedState = 5 + 3;
expect(sharedState).toBe(8);
});
test("使用之前的狀態", () => {
// 這個測試依賴於前一個測試的狀態
expect(sharedState).toBe(8);
});集成測試(並發執行)
匹配 glob 模式的測試文件中的測試會自動並發運行:
ts
import { test, expect } from "bun:test";
// 由於文件名匹配 concurrentTestGlob,這些測試會自動並發運行
// 當文件匹配 concurrentTestGlob 時,使用 test() 等同於 test.concurrent()
// 每個測試都是獨立的,可以並行運行
test("獲取用戶數據", async () => {
const response = await fetch("/api/user/1");
expect(response.ok).toBe(true);
});
// 也可以使用 test.concurrent() 顯式標記為並發
test.concurrent("獲取帖子", async () => {
const response = await fetch("/api/posts");
expect(response.ok).toBe(true);
});
// 也可以使用 test.serial() 顯式標記為順序執行
test.serial("獲取評論", async () => {
const response = await fetch("/api/comments");
expect(response.ok).toBe(true);
});運行測試
bash
# 運行所有測試 - concurrent-*.test.ts 文件將並發運行
bun test
# 覆蓋:強制所有測試並發運行
# 注意:這會覆蓋 bunfig.toml 並並發運行所有測試,無論 glob 如何
bun test --concurrent
# 只運行單元測試(順序執行)
bun test tests/unit
# 只運行集成測試(由於 glob 模式而並發運行)
bun test tests/integration優勢
- 漸進式遷移:通過重命名文件逐個文件地遷移到並發測試
- 清晰的組織:文件命名約定指示執行模式
- 性能:集成測試並行運行更快
- 安全性:單元測試在需要時保持順序執行
- 靈活性:通過重命名文件輕松更改執行模式
遷移策略
遷移現有測試到並發執行:
- 從獨立的集成測試開始 - 這些通常不共享狀態
- 重命名文件以匹配 glob 模式:
mv api.test.ts concurrent-api.test.ts - 驗證測試仍然通過 - 運行
bun test確保沒有競態條件 - 監控共享狀態問題 - 注意不穩定的測試或意外失敗
- 繼續增量遷移穩定的測試 - 不要急於遷移
提示
- 使用描述性前綴:
concurrent-、parallel-、async- - 將相關的順序測試保持在同一目錄中
- 用注釋記錄為什麼某些測試必須保持順序執行
- 使用
test.concurrent()在順序文件中進行細粒度控制 (注意:在concurrentTestGlob匹配的文件中,普通的test()已經並發運行)
多個模式
你可以為不同的測試類別指定多個模式:
toml
[test]
concurrentTestGlob = [
"**/integration/*.test.ts",
"**/e2e/*.test.ts",
"**/concurrent-*.test.ts"
]此配置將在測試匹配任何這些模式時並發運行測試:
integration/目錄中的所有測試e2e/目錄中的所有測試- 項目中任何帶有
concurrent-前綴的測試