review-tests · git:20260603.eb1107d · 2026-06-03 · sha256 08f6415e6fffcf90
review-tests git:20260603.eb1107dA
Immutable. This exact content never changes and is served at /api/v1/blob/08f6415e6fffcf90.
---
name: review-tests
description: 測試體檢診斷器——讀一份既有測試,找出盲點與建議,產出一份 self-contained HTML 報告(不修改任何 source/測試/設定)。報告每條 finding 可 toggle 展開被測 source function 的完整程式碼。補測試請改走 tdd skill。
invocation: review-tests
examples:
- review-tests
- review-tests <目標檔案路徑>
---
# 測試體檢診斷器 (Review Tests)
## 定位
純診斷工具。讀一份既有測試,找出盲點、列出建議,**產出一份 HTML 報告**。
這個 skill 不寫測試、不改測試、不碰 source 與設定。它只負責「指出問題」並把結果呈現成報告,要不要補、怎麼補,由使用者決定。
## 三條硬規則(最優先)
1. **只診斷,不改既有檔案**:不修改任何 source、測試檔或設定檔。唯一允許的寫入是**產生一份新的 HTML 報告檔**到 `.review-tests/`。
2. **補測試走 `tdd`**:報告列出的缺漏,請使用者改用 `tdd` skill 一次一個 red-green 補上,不要在這裡批次補。
3. **只列行為層級盲點**:建議的測試一律用「應該驗證什麼行為」描述。嚴禁為了衝覆蓋率而建議貼著實作細節的測試——那種測試會在 refactor 時誤報,違反 tdd「測行為不測實作」的原則。
## 語言與輸出規範
- 報告內容使用繁體中文(台灣用語)。
- 技術術語保留英文,例如 Vitest、TypeScript、mock、coverage。
- 程式碼區塊、檔案名稱、identifier 嚴禁修改或翻譯。
- **用邏輯通順的中文表達,不要逐字英翻中**:保留 function 名、API 欄位、enum 值等專有名詞的英文原文,但句子要自然、讓使用者一看就懂,重點放在「為什麼是問題」,不要堆術語或生硬直譯。
## 輸入
- **無參數**:詢問使用者目標檔案路徑。
- **指定檔案**:`review-tests <path>`。可給測試檔,或給 source 檔由本工具找出對應的測試檔。
## 流程
1. **定位測試與 source**:讀取目標。若給的是 source 檔,找出對應測試檔;若給測試檔,找出它 import 的 source 檔。若找不到測試檔,回報「尚無測試」並建議改走 `tdd` 從頭建立,流程結束。
2. **檢查**:對照下方四類維度,逐項檢視測試內容,產出 findings。
3. **定位關鍵 source 片段**:為**每一條 finding** 找出被測的那個 `.ts/.vue/.tsx` 函式(不是 spec 裡的 test),記下:函式名稱、source 檔路徑、以及**與這條 finding 真正相關的關鍵行範圍**(通常 3~8 行,不是整個 function——展整個 function 重點會被淹沒、不好找)。
4. **產生 HTML 報告**:依下方規格寫出單檔 HTML 到 `.review-tests/`,自動開啟。
5. 結束。不補測試、不改任何既有檔案。
## 四類檢查維度
每一條發現都要標到**具體的測試檔行號或測試描述**,並對應到一個 source function。
### 1. 斷言有效性 (Assertion Validity)
- 無意義斷言,例如 `expect(true).toBe(true)`。
- 只為了增加覆蓋率而存在、沒有實質驗證的測試。
- 只用 `toBeDefined()` 帶過、沒有檢查具體內容的斷言。
- 註解已算出精確預期值、斷言卻只用 `toBeGreaterThan(0)` 這種偏弱斷言。
### 2. 行為盲點 (Behavior Gaps)
用「行為」角度列出缺漏,描述成「應該驗證 X 行為」,**不是**列覆蓋率數字:
- 缺少 happy path / edge case / 邊界條件。
- 缺少 error handling、異常路徑、null / undefined 處理。
- 重要的邏輯分支(if/else、switch)沒有對應的行為驗證。
- 參數組合(如不同 enum 值、不同模式)覆蓋不全。
### 3. Mock 健康度 (Mock Health)
- 過度 mock,把該測的真實路徑都 mock 掉了。
- mock 資料不符合實際的 TypeScript interface 定義。
### 4. 測試結構 (Structure)
- 是否遵守 AAA(Arrange, Act, Assert)。
- 測試描述是否清楚表達預期行為。
- 是否正確清理測試副作用。
## HTML 報告規格
報告由 skill 目錄下的固定生成器 `render.cjs` 產出。agent **只負責產 findings 資料,不要手刻 HTML**——escape、語法高亮、排版、backlink toggle 全部由生成器內建,手刻容易在 source 片段的 `<` `>` `&` 上出錯。
### 執行步驟
1. 把分析結果寫成一份 findings JSON(schema 見下),存到暫存路徑,例如 `/tmp/<name>-findings.json`。
2. 在**專案根**執行:`node "<本 skill 目錄>/render.cjs" /tmp/<name>-findings.json`
- cwd 必須是專案根,JSON 裡的 source/test 路徑以此為基準。
- 生成器會印出產出的 HTML 絕對路徑。
3. 自動開啟:macOS `open <路徑>`、Linux `xdg-open <路徑>`。
4. **提醒使用者**把 `.review-tests/` 加進 `.gitignore`(若尚未加)。
5. 終端只印一行:HTML 路徑 + 一句健康度摘要。完整內容都在 HTML,不要在終端重印整份報告。
### findings JSON schema
```json
{
"testFile": "src/.../x.spec.ts",
"sourceFile": "src/.../x.ts",
"health": { "level": "良好|及格|待補強", "summary": "一句話總評" },
"sections": [
{ "title": "斷言有效性", "findings": [
{ "desc": "通順中文,保留專有名詞",
"loc": "spec 行 …",
"src": { "fn": "fnName", "file": "(選填,預設 sourceFile)", "from": 297, "to": 300 } } ] },
{ "title": "Mock 健康度", "clean": "無問題……" }
],
"suggestions": [ "應該驗證 …" ]
}
```
- `src`:該 finding 的 backlink 定位。`fn` 是 function 名(toggle 標題用);`from`–`to` 是要展開的**關鍵行範圍**。`file` 選填,跨檔時才填(例如 `.vue` 用到的 composable 在另一支 `.ts`)。
- **只放關鍵幾行,不要整個 function**:擷取真正跟這條 finding 有關的那段邏輯(通常 3~8 行)。展開一整個 function 會讓使用者還要在裡面找重點。展開的是**被測的業務程式**,不是 spec。
- **文字用通順中文,不要逐字直譯**:`desc`/`suggestion`/`summary` 要讀起來自然、講清楚「為什麼是問題」,保留專有名詞英文原文。只支援 `` `code` `` 與 `**bold**` 標記,不要寫原始 HTML(生成器會 escape)。
- `clean` 與 `findings` 二選一:某類無問題就給 `clean` 字串,不硬湊 findings。
### 生成器內建(不需 agent 操心,對齊 html-effectiveness)
- 單檔 HTML、CSS/JS 全 inline、零外部依賴。
- 淺色中性精緻風、健康度 badge(良好綠/及格黃/待補強紅)。
- 每條 finding 的 backlink `<details>` toggle、輕量語法高亮(DOM 建構、不用 innerHTML)、source 片段自動 escape。
## 注意事項
1. **不改既有 code**:唯一寫入是新增 HTML 報告檔。任何 source/測試/設定都不動。
2. **不給數字分數**:只給定性的健康度標示。數字自評不可靠,不當門檻。
3. **測試框架**:主要針對 Vue 3 + TypeScript + Vitest,其他框架可比照原則檢查。
---
## 執行
請提供目標檔案路徑,我將開始體檢、產生 HTML 報告並自動開啟。