實戰背景
編寫單元測試(Unit Tests)是一項耗時且重複性極高的工作。在許多專案中,開發團隊常因為進度緊迫,導致核心業務模組的測試覆蓋率過低,埋下安全隱患。
痛點與問題描述:
我們有一個 C# 專案,其核心計費模組 BillingService.cs 與折扣引擎 DiscountEngine.cs 缺乏單元測試,整體覆蓋率低於 20%。如果讓人工逐個去寫 mock 物件、配置測試斷言,需要耗費至少大半天的時間。
本範例中,我們將向 Oh My Codex (OMX) 下達一個 $ultragoal:「為計費與折扣模組撰寫單元測試,使覆蓋率達到 80% 且無編譯錯誤」。我們將目睹 OMX 如何全自動地探索程式碼、拆解任務,並進入 Autopilot 模式自我修正測試代碼直到成功。
規格定義
本次變更計畫的 ID 為 omx-auto-testing。我們在 OpenSpec 中定義了以下規格:
# 實戰範例 003:openspec/changes/omx-auto-testing/specs/test-coverage/spec.md
## ADDED Requirements
### Requirement: Automated coverage target
`BillingService` 與 `DiscountEngine` 類別的單元測試覆蓋率必須(SHALL)達到 80% 以上。
- 測試必須(SHALL)覆蓋正常計費、折扣疊加、以及邊界值(如金額為 0 或負數)等情境。
#### Scenario: Verify test runner execution
- **WHEN** 執行測試指令 `dotnet test`
- **THEN** 所有新撰寫的單元測試必須(SHALL)全數通過,且不得引入任何編譯期錯誤。
端到端 8 輪 AI 協作紀錄
以下是 You (開發者) 與 OMX Autopilot 之間的完整對話歷史。
── 第 1 輪:下達 $ultragoal 宣告與訪談 ──
- You:
/opsx:explore "我想為 BillingService 與 DiscountEngine 補齊單元測試。請在 OMX 中以 $ultragoal 啟動,目標是測試覆蓋率達 80% 且測試全數通過。" - AI:
好的,已接收到您的
$ultragoal宣告!為了確保任務清單正確,我將啟動
$deep-interview機制。請您確認以下兩點配置:- 測試框架選擇:專案目前已安裝了
xUnit還是NUnit? - Mock 框架選擇:是否使用
Moq進行外部相依性(如IRepository)的模擬?
請提供您的回覆,以便我為您建立精確的任務佇列。
- 測試框架選擇:專案目前已安裝了
── 第 2 輪:完成訪談、$ralplan 審查與任務生成 ──
- You:
我們使用 xUnit 與 Moq。請先用 $ralplan 檢查 coverage 目標、mock 邊界與驗收方式;確認後交給 $ultragoal。 - AI:
收到。
$ralplan先檢查測試策略:coverage 只計核心模組、外部 payment / repository 以 Moq 隔離,dotnet test與 coverage threshold 都是完成證據。Critic 未發現阻塞後,$ultragoal建立執行 missions:- Mission 1:為
DiscountEngine.cs撰寫單元測試(包含折扣邊界值測試)。 - Mission 2:為
BillingService.cs撰寫單元測試(使用 Moq 模擬IPaymentGateway與IOrderRepository)。 - Mission 3:執行
dotnet test檢驗覆蓋率並進行增量錯誤自修復。
任務已成功載入本地的
.omx/queue.json!現在,我將啟動 Autopilot 模式,全自動執行這些任務。OMX staged flow:
$deep-interview → $ralplan → $ultragoal執行階段:Autopilot engaged. Entering Mission 1. - Mission 1:為
── 第 3 輪:Autopilot 執行任務 1 (寫折扣測試) ──
- You:
請報告任務 1 的執行狀態與產出的測試原始碼。 - AI:
Implementing: omx-auto-testing
正在處理任務 1/3 (Autopilot):為
DiscountEngine撰寫 xUnit 測試。我已自動定位了折扣引擎的實作,並在
tests/DiscountEngineTests.cs中建立了以下測試代碼,覆蓋了多重折扣疊加與負值金額防禦:[Fact] public void CalculateDiscount_NegativeAmount_ThrowsArgumentException() { var engine = new DiscountEngine(); Assert.Throws<ArgumentException>(() => engine.CalculateDiscount(-100, "WINTER10")); }✓ 任務 1.1 執行成功。自動進入下一項任務。
── 第 4 輪:建立提案 ──
- You:
/opsx:propose "自動化補完計費模組單元測試,提昇覆蓋率至 80%" - AI:
好的,提案
omx-auto-testing已經正式在 OpenSpec 註冊!- proposal.md: 說明測試自動化補完與覆蓋率要求。
- specs/test-coverage/spec.md: 定義 80% 覆蓋率場景。
- tasks.md: 已與 OMX 任務清單完成同步對齊。
請輸入
/opsx:apply讓 Autopilot 繼續在背景實作任務 2「寫計費服務測試」。
── 第 5 輪:Autopilot 執行任務 2 (寫計費測試) ──
- You:
/opsx:apply - AI:
Implementing: omx-auto-testing (schema: spec-driven)
正在處理任務 2/3 (Autopilot):為
BillingService撰寫測試(搭配 Moq 模擬)。我已在
tests/BillingServiceTests.cs中建立測試。由於BillingService相依於IPaymentGateway,我使用 Moq 進行了模擬:[Fact] public async Task ProcessPayment_ValidOrder_ReturnsSuccess() { var mockGateway = new Mock<IPaymentGateway>(); mockGateway.Setup(g => g.ChargeAsync(It.IsAny<decimal>())).ReturnsAsync(true); var service = new BillingService(mockGateway.Object); var result = await service.ProcessPaymentAsync(new Order { TotalAmount = 100 }); Assert.True(result.IsSuccess); }✓ 任務 2 實作完成。自動進入任務 3。
── 第 6 輪:Autopilot 執行任務 3 與自動修復 (Error Self-healing) ──
- You:
繼續執行任務 3(測試與覆蓋率驗證)。 - AI:
Implementing: omx-auto-testing
正在處理任務 3/3 (Autopilot):執行測試與自修復。
我在背景執行了
dotnet test /p:CollectCoverage=true。 首次建置失敗:BillingServiceTests.cs(12,24): error CS0246: 找不到型別或命名空間名稱 'Order'。$plan(自動修復中): 偵測到命名空間缺失。我自動在
BillingServiceTests.cs的頂部補上了using Models;。第二次建置與測試:
Build Succeeded. All tests passed. Coverage: 84.2%.✓ 任務 3 全數通過!覆蓋率達 84.2%(已突破 80% 目標)。
── 第 7 輪:執行驗證與歸檔 ──
- You:
做得太好了。執行 verify 與 archive 以結束這次的變更計畫。 - AI:
Implementing: omx-auto-testing
執行驗證與歸檔:
- 驗收規格:確認
BillingService與DiscountEngine覆蓋率大於 80%,且無編譯錯誤。 - 合併變更:已將測試規格合併至主規格庫。
- 計畫歸檔:清理變更計畫目錄。
Archive Complete
變更計畫已順利歸檔!
- 驗收規格:確認
── 第 8 輪:總結 Autopilot 效益 ──
- You:
請列出本次 Autopilot 與人工手動編寫相比的效益分析。 - AI:
本次全自動測試補完的數據指標如下:
評估維度 人工編寫 (估計) OMX Autopilot (實際) 時間花費 約 4.5 小時 (手動撰寫 + 逐步排查編譯錯誤) 185 秒 (大幅縮短 98%) 測試通過率 N/A (需經歷多次人工修改) 100% (透過 $plan 增量修正) Token 費用 N/A $1.85 USD 代碼變更 新增 2 個測試檔案,共 142 行測試代碼 完全符合 Autopilot 完美展現了其在重複性代碼撰寫(如編寫單元測試)上的極致效率。