← 返回範例總覽
中等 20 mins

實戰範例 10:為核心工具方法補上單元測試

為專案的工具方法補上單元測試,提升測試覆蓋率,並整合至 Vitest 測試框架中。

使用指令 /opsx:propose/opsx:apply/opsx:archive
#補上測試#Vitest#單元測試#測試驅動

實戰背景

在長週期的軟體專案中,沒有測試保護的程式碼就如同沒有地基的房屋,任何一次細微的修改或重構都可能意外引入嚴重的錯誤 (Regression)。為了保障核心工具函式 (Utility Functions) 的正確性,為其撰寫完備的單元測試 (Unit Tests) 是不可或缺的防線。

本範例中,我們將為專案中負責「URL 格式化與清理」的工具函數 formatUrl.ts 補上單元測試,並整合至 Vitest 測試框架。我們將使用 OpenSpec 的 快速開發工作流 (Quick Flow) 來進行此項任務。


規格定義

本次變更計畫的 Capability 為 testing-coverage。我們預計在規格增量 (Spec Delta) 中定義以下驗收標準:

## ADDED Requirements

### Requirement: Utility function tests
The project SHALL maintain unit tests for all shared utility functions using Vitest to prevent code regressions.

#### Scenario: Url formatting edge cases
- **WHEN** formatting a raw url string with leading/trailing spaces or mixed slashes
- **THEN** the test suite SHALL verify the output is sanitized and return a canonical path format

端到端 6 輪 AI 協作紀錄

以下是 You 與 AI 助手的完整對話歷史。

── 第 1 輪:建立計畫與提案 ──

  • You:
    /opsx:propose "為 src/utils/formatUrl.ts 補上單元測試,使用 Vitest 框架,至少覆蓋 5 種邊界情況"
    
  • AI:

    好的,已建立變更計畫 add-unit-tests-to-utils

    • 建立 proposal.md: 說明為什麼要為此工具函數補上單元測試。
    • 建立 specs/testing-coverage/spec.md: 新增 URL 格式化邊界情況測試的驗收情境 (Scenario)。
    • 建立 tasks.md: 包含以下 3 個實作任務:
      • 1.1 安裝並設定 Vitest 測試框架與執行指令
      • 1.2 於 tests/formatUrl.test.ts 中撰寫 5 種邊界情況測試
      • 1.3 執行測試並確認覆蓋率達 100%

    請執行 /opsx:apply 開始實作。


── 第 2 輪:審查與微調提案 ──

  • You:
    這 5 種情況要包含:空字串、純斜線、重複斜線、前後空白字元、以及帶有 Query Parameter 的情況。
    
  • AI:

    好的,已使用 /opsx:update 更新文件:

    • 更新 design.md:明確定義 5 種 URL 測試案例的輸入與預期輸出結果。
    • 更新 tasks.md:將任務 1.2 細化,條列出該 5 種邊界情況的程式碼撰寫。

    一致性更新完成。現在您可以執行 /opsx:apply 了。


── 第 3 輪:實作任務 1 (安裝與設定 Vitest) ──

  • You:
    /opsx:apply
    
  • AI:

    Implementing: add-unit-tests-to-utils (schema: spec-driven)

    正在處理任務 1/3:安裝並設定 Vitest 測試框架。

    我已在專案中安裝 vitest 並於 package.json 的 scripts 中新增 test: "vitest run" 命令。

    ✓ 任務已完成。已將 tasks.md 中的任務 1.1 標記為完成。

    準備好進入任務 1.2「撰寫邊界測試」了嗎?


── 第 4 輪:實作任務 2 (撰寫測試代碼) ──

  • You:
    繼續撰寫測試。
    
  • AI:

    Implementing: add-unit-tests-to-utils

    正在處理任務 2/3:於 tests/formatUrl.test.ts 中撰寫 5 種邊界情況測試。

    我已建立了測試檔案,針對 formatUrl 進行了以下 5 種情境的 assertion 驗證:

    import { describe, it, expect } from 'vitest';
    import { formatUrl } from '../src/utils/formatUrl';
    
    describe('formatUrl 工具函式測試', () => {
      it('1. 應處理前後空白', () => {
        expect(formatUrl('  /path/name  ')).toBe('/path/name');
      });
      it('2. 應處理重複斜線', () => {
        expect(formatUrl('///path//name')).toBe('/path/name');
      });
      it('3. 應處理空字串', () => {
        expect(formatUrl('')).toBe('/');
      });
      it('4. 應處理純斜線', () => {
        expect(formatUrl('///')).toBe('/');
      });
      it('5. 應保留 Query String', () => {
        expect(formatUrl('/path?ref=test')).toBe('/path?ref=test');
      });
    });
    

    ✓ 任務已完成。已將任務 1.2 標記為完成。

    剩下最後一個任務:執行並檢查覆蓋率。是否繼續?


── 第 5 輪:實作任務 3 (執行與檢查覆蓋率) ──

  • You:
    繼續執行測試。
    
  • AI:

    Implementing: add-unit-tests-to-utils

    正在處理任務 3/3:執行測試並確認覆蓋率。

    我已執行 pnpm run test。測試結果回報:

    • ✓ 5/5 test cases passed.
    • formatUrl.ts 語句 (Statement) 與分支 (Branch) 覆蓋率均達到 100%。

    ✓ 任務已完成。已將任務 1.3 標記為完成。

    所有任務已完成!是否執行驗證與歸檔?


── 第 6 輪:驗證與歸檔 ──

  • You:
    執行 verify 並歸檔。
    
  • AI:

    好的,我為您執行 /opsx:verify/opsx:archive

    1. 驗證成功:測試案例完全覆蓋了 Scenario: Url formatting edge cases 定義的邊界條件。
    2. 智慧同步:已將暫存規格合併至主規格 openspec/specs/testing-coverage/spec.md
    3. 目錄歸檔:已將計畫資料夾移至 openspec/changes/archive/2026-07-14-add-unit-tests-to-utils/

    Archive Complete

    變更計畫已成功歸檔!