安裝與環境設定 — Unit Test Orchestrator 使用指南
從環境需求、安裝步驟,到跑出第一個測試工作流程。本文深入最常用、不需要 Docker 的 Unit Test Orchestrator — 七種使用情境、四階段流程,以及一個由淺入深、共六個階段的練習專案,讀完就能跑出你的第一個 Agent Orchestration 工作流程。
前言
前一篇解析了架構設計 — 為什麼 Orchestrator 是 Skill、bypassPermissions、計時 Hook、Writer 分割這些關鍵決策。這一篇開始進入實作:從環境安裝到實際跑出第一個測試工作流程。
原本想把四種 Orchestrator 的使用寫在同一篇,但內容太多:光是 Unit Test 一個 Orchestrator,就有七種使用情境、六個練習階段,還有完整的四階段工作流程細節,全部塞進一篇會太雜。所以拆成兩篇 — 這一篇先把共用的安裝與環境設定講清楚,再深入 Unit Test Orchestrator(最常用、不需要 Docker、最適合入門)。下一篇再處理需要額外環境的三個進階 Orchestrator。
環境需求
必要工具
| 工具 | 說明 |
|---|---|
| Claude Code CLI | 最新版本,claude 指令可在終端機執行 |
| .NET SDK | 支援 net8.0 / net9.0 / net10.0,至少安裝一個版本 |
| Node.js | 用於安裝 Agent Skills(npx skills install) |
進階測試額外需要(本篇用不到,下一篇會用到)
Unit Test 不需要 Docker。但如果你之後要用 Integration 或 Aspire Orchestrator,會需要:
| 工具 | 適用測試 | 說明 |
|---|---|---|
| Docker Desktop | Integration、Aspire | Testcontainers / Aspire 容器編排需要 |
| .NET Aspire workload | Aspire | dotnet workload install aspire |
驗證工具已安裝
claude --version
dotnet --list-sdks
node --version安裝步驟
步驟 1:Clone 儲存庫
git clone https://github.com/kevintsengtw/dotnet-testing-agent-orchestration-claude.git
cd dotnet-testing-agent-orchestration-claude這個 repo 內建了所需的 .claude/ 目錄 — 4 個 Orchestrator Skill 與 dotnet-test 執行器、16 個 Subagent 定義檔,以及計時 Hook 腳本。
步驟 2:安裝 Agent Skills
外部的 Agent Skills 提供各種 .NET 測試技術的知識庫(AutoFixture、NSubstitute、Testcontainers 等),需從 dotnet-testing-agent-skills 安裝:
npx skills install dotnet-testing-agent-skills安裝完成後,這 29 個 Skills 會安裝到 Claude Code 的用戶 Skills 目錄,供所有使用 Claude Code 的專案共用。
驗證:在 Claude Code 對話中輸入 /,確認清單中可看到 dotnet-testing-autofixture-basics、dotnet-testing-nsubstitute-mocking 等 Skills。
步驟 3:確認 .claude/ 目錄結構
完成步驟 1、2 後,.claude/ 的預期結構如下:
.claude/
├── agents/ ← repo 內建(16 個 Subagent)
│ ├── dotnet-testing-analyzer.md Unit 組
│ ├── dotnet-testing-writer.md
│ ├── dotnet-testing-executor.md
│ ├── dotnet-testing-reviewer.md
│ ├── dotnet-testing-advanced-integration-*.md Integration 組(4 個)
│ ├── dotnet-testing-advanced-aspire-*.md Aspire 組(4 個)
│ └── dotnet-testing-advanced-tunit-*.md TUnit 組(4 個)
│
├── hooks/ ← repo 內建(計時 Hook)
│ ├── dotnet-testing-agent-timer-pre.sh
│ ├── dotnet-testing-agent-timer-post.sh
│ └── install-hooks.js
│
└── skills/
│ ── repo 內建(5 個)──
├── dotnet-test/ .NET 測試執行器
├── dotnet-testing-orchestrator-unit/
├── dotnet-testing-orchestrator-integration/
├── dotnet-testing-orchestrator-aspire/
├── dotnet-testing-orchestrator-tunit/
│
│ ── npx skills install 安裝後新增(29 個)──
├── dotnet-testing-autofixture-basics/
├── dotnet-testing-nsubstitute-mocking/
└── ...(其餘 27 個 Agent Skills)repo 內建的是 4 個 Orchestrator Skill 加 1 個 dotnet-test 執行器(共 5 個 Skill)與 16 個 Subagent;另外 29 個 Agent Skills 由步驟 2 安裝,因此 .claude/skills/ 下最終會有 34 個 Skill。
步驟 4:安裝計時 Hook(可選,但強烈建議)
計時 Hook 會在每個 Subagent 執行前後自動追蹤耗時,並把時間資訊注入到 Claude 的 context 中。技術上它是可選的 — 沒裝工作流程照樣能跑;但強烈建議裝上:有了每個階段的耗時,你才看得出時間花在哪、哪個 Subagent 是瓶頸,這在跑比較久的 Integration、Aspire 工作流程時特別有用。它只需要裝一次,幾乎沒有不裝的理由。
在 repo 根目錄執行:
node .claude/hooks/install-hooks.js步驟 5:驗證安裝
啟動 Claude Code 後,在對話中輸入 /,確認以下斜線指令可用:
| 斜線指令 | 對應 Orchestrator |
|---|---|
/dotnet-testing-orchestrator-unit | 單元測試 |
/dotnet-testing-orchestrator-integration | 整合測試 |
/dotnet-testing-orchestrator-aspire | Aspire 測試 |
/dotnet-testing-orchestrator-tunit | TUnit 測試 |
四個指令都出現在清單中,就表示安裝完成。
在 VS Code 裡執行:先開好 Bypass permissions
上一篇提過,每個 Subagent 的定義裡都設了 bypassPermissions: true,讓 Executor 跑 dotnet build、dotnet test 時不必每個指令都等你確認。但如果你用的是 VS Code 的 Claude 擴充套件,擴充套件本身還有一層權限把關 — 預設每執行一個指令都會跳出確認,四階段流程會被一直打斷。要讓它順順跑完,有兩個地方要設定。
第一,打開 VS Code 設定(Settings),搜尋 claude,把 Claude Code: Allow Dangerously Skip Permissions 勾起來。

第二,光開設定還不夠 — 還要在 chat panel 把模式切到 Bypass permissions(按 Shift + Tab 可以循環切換各種模式)。切到這個模式後,Claude 執行指令前就不會再逐一要求確認。

要提醒的是,bypass 顧名思義是跳過所有確認,官方建議只在隔離環境(容器、VM、沙箱)使用。這套測試工作流程的指令範圍很明確 — 建置、跑測試、在測試專案內寫檔 — 風險可控,但你還是要清楚它在替你做什麼。另外,這是 Claude Code 標準的權限模式,不限特定付費方案;如果你在設定裡看不到、或切不過去,通常是被使用者自己的設定或(Team / Enterprise)組織的管理設定停用了。
Unit Test Orchestrator 使用
環境就緒後,我們從最常用的 Unit Test Orchestrator 開始。它適用於任何需要為 .NET 類別產生 xUnit 單元測試的情境 — 純函式計算、有 Mock 依賴的服務類別、FluentValidation 驗證器、含時間或檔案系統抽象的類別。
測試技術棧:xUnit 2.9 + NSubstitute + AutoFixture + AwesomeAssertions + Bogus + FakeTimeProvider + MockFileSystem。
基本操作
在 Claude Code 工作階段中輸入斜線指令觸發 Orchestrator,並提供目標類別的資訊:
/dotnet-testing-orchestrator-unit 為 OrderService 撰寫單元測試。
被測試目標:src/MyApp.Core/Services/OrderService.cs
測試專案:tests/MyApp.Core.Tests/MyApp.Core.Tests.csproj
說明:(可選,用於補充特殊需求)指令觸發後,Orchestrator 會依序自動啟動四個 Subagent:Analyzer → Writer → Executor → Reviewer,全程無需手動介入。
七種使用情境
Unit Test Orchestrator 會根據被測類別的特性,自動決定要用哪些測試技術。以下七種情境涵蓋了大部分的單元測試需求。
情境 1:純函式計算類別
目標類別無外部依賴,只有純計算邏輯(如溫度轉換、數值運算)。
「為 TemperatureConverter 撰寫單元測試,純函式溫度轉換類別,無外部依賴」
Analyzer 判斷類別無建構子依賴,只用基礎技能;Writer 不引入 Mock,直接以 [Fact] / [Theory] 測試純計算邏輯。命名範例:CelsiusToFahrenheit_攝氏0度_應回傳華氏32度。
情境 2:有 Mock 依賴的服務類別
建構子注入一個或多個介面(如 IWeatherService、INotificationService),需要 Mock 隔離外部依賴。
「為 WeatherAlertService 撰寫單元測試」
Analyzer 偵測到介面依賴,要求載入 NSubstitute 技能;Writer 用 Substitute.For<IXxx>() 建立 Mock 並設定 Stub 行為,非同步方法用 await 正確測試。
情境 3:AutoFixture + Bogus 測試資料
操作的模型包含循環參考或複雜結構(如 Employee、Department),需要自動產生測試資料。
「為 EmployeeService 撰寫單元測試,Employee 模型含循環參考,需要 AutoFixture + Bogus 產生測試資料」
Writer 用 OmitOnRecursionBehavior 處理循環參考,擬真假資料透過 Bogus.Faker 產生。
情境 4:FakeTimeProvider 時間依賴
建構子注入 TimeProvider,方法內部依賴目前時間判斷(如訂閱有效期、排程觸發)。
「為 SubscriptionService 撰寫單元測試」
Writer 用 FakeTimeProvider 在測試中凍結或快轉時間。命名範例:IsSubscriptionActive_訂閱期間內_應回傳true。
情境 5:MockFileSystem 檔案系統抽象
建構子注入 IFileSystem,操作檔案讀寫或目錄處理。
「為 ConfigurationLoader 的所有公開方法撰寫單元測試」
Writer 用 MockFileSystem 在記憶體中建立虛擬檔案與目錄,測試涵蓋檔案存在/不存在、讀寫成功/失敗、路徑異常等情境。
情境 6:FluentValidation 驗證器
目標類別繼承 AbstractValidator<T>,需用 FluentValidation TestHelper 模式測試驗證規則。
「為 OrderValidator 撰寫單元測試」
Analyzer 將 targetType 設為 validator;Writer 用 validator.TestValidate(model) 搭配 ShouldHaveValidationErrorFor() / ShouldNotHaveValidationErrorFor()。值得注意的是,Validator 類別永遠使用單一 Writer,不會被分割,以確保驗證規則的一致性。
情境 7:多目標類別平行處理
一次指定多個目標類別,Orchestrator 自動以平行方式分析與撰寫。
「為 OrderProcessingService、WeatherAlertService 撰寫單元測試」
Orchestrator 平行啟動兩個 Analyzer 與兩個 Writer,但 Executor 循序執行(共用同一測試專案,避免 dotnet build 衝突),最後彙整呈現概覽表格與各目標詳細結果。
四階段工作流程
每次觸發指令後,Orchestrator 依序執行四個階段:
Phase 1 — Analyzer 分析:讀取被測目標原始碼,判斷類別類型(service / validator / legacy),識別建構子依賴(I* 介面要 Mock、TimeProvider 用 FakeTimeProvider、IFileSystem 用 MockFileSystem),評估需要哪些 Agent Skills,估算各方法的測試情境數量,產出 JSON 分析報告。
Phase 2 — Writer 撰寫:讀取 Analyzer 的交接 JSON,按需載入對應 Agent Skills,按中文三段式命名(方法名_情境描述_預期結果)產生測試。當方法數 > 5 或情境數 > 20 時,會分割為兩個平行 Writer,且兩者的斷言風格、using 排列、初始化方式必須完全一致。所有斷言使用 AwesomeAssertions(.Should()),禁止 xUnit 原生 Assert.*。
Phase 3 — Executor 建置與執行:透過 repo 內建的 dotnet-test Skill 以 build-first 流程執行 — 先 dotnet build 確認可編譯,再用 dotnet test --no-build 確認通過,必要時以 --filter 鎖定特定測試。遇到編譯錯誤或測試失敗,自行分析並修正,最多 3 輪,超過則回報失敗。
Phase 4 — Reviewer 審查:讀取測試程式碼與三個交接檔案,審查命名規範、斷言品質、單一行為原則、Mock 設定、AutoFixture 一致性、覆蓋完整性,產出評分與改善建議。Orchestrator 呈現完整報告後,等待使用者決定是否啟動修改流程(Writer 修改 → Executor 重新執行 → Reviewer 重新審查)。
實際跑一次:SubscriptionService
講完四階段,來看實際跑一次長什麼樣。這裡用練習專案裡的 SubscriptionService(就是情境 4 那個依賴 TimeProvider 的類別)當例子,下這個指令:
/dotnet-testing-orchestrator-unit 為 SubscriptionService 撰寫單元測試。
被測試目標:samples/unit/practice/src/Practice.Core/Services/SubscriptionService.cs
測試專案:samples/unit/practice/tests/Practice.Core.Tests/Practice.Core.Tests.csproj觸發後,Orchestrator 會先做 Phase 0 前置清理(確認沒有殘留的 .orchestrator/ 目錄),再進入階段 1,把 Analyzer 委派出去。

階段 1 的 Analyzer 分析出這個類別有 6 個方法、依賴一個 TimeProvider,判斷需要載入哪幾個 Agent Skills,並寫出 analysis.json。因為方法數與情境數超過門檻,這裡觸發了 Writer 分割 — 用貪心分組把方法拆成兩組,啟動兩個平行 Writer(階段 2)。

兩個 Writer 寫完後進入階段 3,Executor 以 build-first 流程執行 — 先 dotnet build 確認可編譯(建置成功、零警告零錯誤),再 dotnet test 跑測試。

這次測試初次建置就全數通過、零修正輪次。接著階段 4 的 Reviewer 審查品質,最後 Orchestrator 執行 Phase 5 後置清理,把整個 .orchestrator/ 暫存目錄清掉。

最後 Orchestrator 會給出一份完整報告:產出了哪些測試檔案、執行結果、品質評分與改善建議。

值得一提的是,這次 Reviewer 抓到了 Analyzer 的一個疏漏 — 有個公開方法 GetSubscriptionStatus 根本沒被測到(Analyzer 只算了 6 個方法,實際有 7 個),並列出建議補上的測試案例。這正是四階段裡 Reviewer 這一關的價值:它會回頭挑出前面階段漏掉的東西,而不是測完就算數。

報告最後那張「各階段耗時」表,就是前面步驟 4 那個計時 Hook 的產物 — 一眼就看得出時間花在哪(這次 Writer 最久)。看完報告,Orchestrator 會停下來等你決定要不要套用 Reviewer 的修改建議;要套用的話,就會進入「Writer 修改 → Executor 重新執行 → Reviewer 重新審查」的循環。
練習專案
repo 內附了一個練習專案在 samples/unit/practice/,由淺入深分為六個學習階段:
| Phase | 目標類別 | 學習重點 |
|---|---|---|
| Phase 1 | TemperatureConverter | AAA Pattern、[Fact] / [Theory]、AwesomeAssertions |
| Phase 2 | WeatherAlertService | NSubstitute Mock/Stub、非同步方法測試 |
| Phase 3 | EmployeeService | AutoFixture、循環參考處理、Bogus 假資料 |
| Phase 4 | SubscriptionService、ConfigurationLoader | FakeTimeProvider、MockFileSystem |
| Phase 5 | OrderProcessingService | 多 Mock 協調的複雜業務邏輯 |
| Phase 6 | LegacyReportGenerator | 遺留程式碼識別、重構策略、Characterization Test |
練習專案支援 net8.0 / net9.0 / net10.0 三個版本。練習產生的測試檔案僅供練習,不應 commit,要還原初始狀態可執行:
git checkout -- samples/unit/practice/tests/常見問題排查
Agent Skills 未載入:Writer 找不到 dotnet-testing-autofixture-basics 等技能,或斜線指令無法使用。重新執行 npx skills install dotnet-testing-agent-skills,安裝後重啟 Claude Code 工作階段。
Writer 沒有觸發分割:當方法數超過 5 或情境數超過 20 時應自動分割為兩個平行 Writer。若沒分割,可能是 Analyzer 估算的情境數偏低,可在指令中補充說明該類別的複雜度提示。注意 Validator 類別永遠不分割。
AutoFixture 循環參考錯誤:dotnet test 出現 ObjectCreationException。在 Fixture 初始化時加入 OmitOnRecursionBehavior,或改用 Builder 方式手動建立含循環參考的物件。
xUnit Theory 參數型別問題:decimal 無法直接用於 [InlineData](xUnit 限制),編譯會出現 An attribute argument must be a constant expression。改用 [MemberData] 傳遞 decimal 參數。
斜線指令無法使用:確認 .claude/skills/ 下各目錄有 SKILL.md、目錄名稱完全吻合,重啟 Claude Code 讓 Skills 重新載入。
附帶一提:跟 Copilot 版的一次耗時對照
這套測試工作流程,我更早是在 GitHub Copilot 上做的(dotnet-testing-agent-orchestration,最後一個版本停在 v2.0.0)。那個版本從 v1 改版時,其中一項重點就是把分階段耗時內建進流程,所以它跟 Claude 版一樣會輸出每個階段的耗時 — 剛好可以把兩邊各跑一次的數字放在一起看。
要先說清楚,這不是嚴謹的 benchmark:兩次跑的被測類別不一樣(Claude 版是前面那個 SubscriptionService,Copilot v2.0.0 版是練習專案裡的 OrderProcessingService),平台與模型也不同(一邊跑在 Claude Code、一邊跑在 GitHub Copilot,底層模型一個是 Claude、一個是 GPT-5.3-Codex)。所以下面的數字只能當作「各自跑一次的體感」,不是控制變因後的對照。
| 階段 | Claude 版(SubscriptionService) | Copilot v2.0.0 版(OrderProcessingService) |
|---|---|---|
| Analyzer | 1 分 18 秒 | 2 分 55 秒 |
| Writer | 2 分 25 秒 | 2 分 25 秒 |
| Executor | 52 秒 | 1 分 30 秒 |
| Reviewer | 1 分 8 秒 | 1 分 52 秒 |
| 總計 | 5 分 43 秒 | 9 分 46 秒 |
(Copilot 版的數字取自 v2.0.0 timing log 的各階段起訖時間換算,Claude 版取自前面那次 SubscriptionService 的各階段耗時表。)
就算把「被測類別不同」這個變因放進去,整體量級的差距還是看得出來 — 這次 Claude 版的總時間大約是 Copilot v2.0.0 那次的六成,差最多的是 Analyzer 這個分析階段。Writer 兩邊剛好都是 2 分 25 秒,則純粹是巧合。但還是回到那句話:各只跑一次、被測類別又不同,這張表看個大概的量級就好,真要比較得固定被測對象、各跑多次才算數。
小結
這一篇把安裝走了一遍 — clone repo、裝 Agent Skills、(強烈建議)裝計時 Hook、驗證斜線指令 — 然後深入了最常用的 Unit Test Orchestrator:七種使用情境、四階段工作流程,以及附帶的六階段練習專案。
選 Unit Test 當作入門是有原因的:它不需要 Docker、涵蓋的測試技術最廣(從純函式到 Mock、AutoFixture、TimeProvider、MockFileSystem、FluentValidation),跑一輪下來就能對整個 Agent Orchestration 的運作有完整體感。練習專案的六個 Phase 也是按這個邏輯設計的,建議照順序跑一遍。
下一篇會接著介紹其餘三個 Orchestrator — Integration、Aspire、TUnit。它們需要額外的環境(Docker、Aspire workload)或不同的執行方式,但共用同一套安裝基礎與四階段架構。
參考資源
- dotnet-testing-agent-orchestration(Claude Code 版):https://github.com/kevintsengtw/dotnet-testing-agent-orchestration-claude
- dotnet-testing-agent-skills:https://github.com/kevintsengtw/dotnet-testing-agent-skills
- Claude Code 官方文件:https://docs.claude.com/en/docs/claude-code/overview
- Claude Code Skills:https://docs.claude.com/en/docs/claude-code/skills
純粹是在寫興趣的,用寫程式、寫文章來抒解工作壓力