# Test Assertion Design

> Assertion design judgment framework for flaky and design-quality issues. Use when writing tests, reviewing assertions, diagnosing flaky tests, or deciding if a timing/float/cache assertion is appropriate. Do NOT use for API syntax or refactoring.

- Skill: `tarrragon/test-assertion-design` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add tarrragon/test-assertion-design`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tarrragon/test-assertion-design/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: tarrragon (https://skillmd.com/u/tarrragon)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/tarrragon/test-assertion-design

---


# Test Assertion Design

斷言設計判斷概念框架。職責：識別「此斷言設計是否合理」，提供跨語言判斷標準。不提供測試寫法或重構步驟。

## 斷言品質三問

設計或審查斷言時，依序回答三個問題。任一問題答「否」即進入對應的類型判斷：

| 問題 | 判斷標準 | 「否」時對應類型 |
|------|---------|----------------|
| 確定性 | 同一程式碼在任何執行環境下，pass/fail 結果一致？ | 類型 1–6（確定性失效） |
| 聚焦性 | 此測試案例只驗證一個行為面向？ | 類型 8–9（設計問題） |
| 隔離性 | 此測試不依賴其他測試建立的狀態或執行順序？ | 類型 7（隔離違反） |

## 確定性斷言的基礎形態（無問題，作為對比基線）

以下 4 種確定性斷言類型符合三問標準，可直接放功能測試套件：

| 確定性類型 | 說明 |
|-----------|------|
| 功能正確性 | 輸出值直接比對固定預期值 |
| 邏輯不變式 | 驗證數學/邏輯關係（a < b、rate < 1.0），兩側均非環境依賴值 |
| 結構驗證 | 驗證欄位存在、型別正確、陣列長度 |
| 資源清理 | 驗證洩漏偵測差值（前後 count 差值 = 0），用差值而非絕對值 |

## 9 類型問題斷言分類決策表

### 判斷軸

9 類型問題依問題本質分為兩族（partition，互斥）：

- **環境依賴 flaky 族**（類型 1–4）：斷言結果受執行環境影響，核心問題是「確定性」
- **斷言設計族**（類型 5–9）：斷言內容設計不當，核心問題是「驗什麼」

此分族與斷言品質三問為不同視角：三問是快速分流入口（任一否即識別問題族群）；分族是依問題本質歸類（幫助理解根因、選擇對應設計原則）。

### 問題類型表

| 類型 | 問題本質 | 識別信號 | 設計原則 | 來源 |
|------|---------|---------|---------|------|
| 1. 計時硬門檻 | 使用單次計時值與絕對毫秒數比較作為 pass/fail | 計時差值對比 `N ms` 常數 | 受機器負載影響；功能測試套件禁用；效能門檻移至隔離執行環境 | 實證驗證 |
| 2. 高精度浮點 | 浮點計算結果用超過 2 位小數精度斷言 | `toBeCloseTo(x, numDigits)` 其中 numDigits 超過 2 | IEEE 754 浮點路徑在跨 JIT 環境下末位數字不保證一致；超過 2 位精度需附確定性計算理由 | 實證驗證 |
| 3. 相對計時比較 | 以兩次執行時間的差距或倍數比較驗證快取效果 | `secondRunTime < firstRunTime * K` | 相對計時同樣受 GC/JIT 影響；改用快取命中率或物件參考等價（identity equality）驗證 | 實證驗證 |
| 4. 記憶體絕對值 | 用堆積記憶體使用絕對上限作為 pass/fail | `heapUsed < N MB` 在功能測試套件 | 記憶體使用受 GC 時機影響；改用前後差值偵測洩漏（差值 = 0）而非絕對上限 | 實證驗證 |
| 5. 非同步時序 | 斷言非同步操作尚未完成時的中間狀態 | 斷言位置在觸發事件之後但等待機制之前；結果隨執行速度改變 | 等待最終狀態再斷言；等待機制因框架而異但「等完成再斷言」原則跨語言一致 | W1-024 推導 |
| 6. 亂數輸出 | 斷言由不可控隨機源驅動的特定輸出值 | 斷言依賴具體的隨機生成值（特定 ID、特定排序、特定分組） | 隨機源必須可控；斷言驗證演算法行為（分佈特性、邊界條件），不斷言特定隨機輸出 | W1-024 推導 |
| 7. 測試隔離違反 | 測試依賴其他測試建立的副作用或特定執行順序 | 測試單獨執行通過但全套件執行失敗；測試順序改變影響 pass/fail | 每個測試自建前置條件，teardown 還原所有共享狀態；隔離違反問題跨語言同形 | W1-024 推導 |
| 8. 快照過度覆蓋 | 快照比對整體輸出結構，非業務相關的格式變更觸發 false positive | 修改一個不相關欄位或樣式，整個快照紅燈 | 快照粒度匹配驗證意圖；業務邏輯驗收用欄位/屬性斷言，全結構快照只用於偵測非預期變更 | W1-024 推導 |
| 9. 斷言過度集中 | 單一測試案例驗證多個行為面向，前面的斷言失敗遮蔽後面的 | 一個 test case 驗 10 個以上屬性，或測試名稱難以用單一行為描述 | 一測試案例一行為面向；斷言數量與被測行為的複雜度成比例，不與輸出結構大小成比例 | W1-024 推導 |

## 不在範圍聲明

此 skill 提供判斷概念，以下內容屬下游層級，不在此 skill 範圍：

| 不在範圍的內容 | 所在層級 |
|--------------|---------|
| 具體測試寫法（`toBeLessThan`、`pumpAndSettle`、`testing.T`） | 語言/框架文件 |
| 重構步驟（如何將計時斷言改為功能斷言） | 實作代理人職責 |
| 精度數字規定（numDigits <= 2）、目錄結構規定（tests/perf/） | 專案 rules 層 |
| 效能測試 SLA 門檻設定 | 專案決策層 |

專案 rules 層：`.claude/rules/core/test-assertion-design-rules.md`（本專案 Chrome Extension/JS/Jest 專屬規則）

## 專案類型脈絡（按需讀取）

各類型在不同專案中有脈絡差異。讀取對應 reference 取得輕量提示：

| 情境 | 讀取 reference |
|------|--------------|
| WEB 類專案（JS/TS + Jest/Vitest/Playwright） | `references/web-testing-context.md` |
| APP 類專案（Flutter/React Native） | `references/app-testing-context.md` |
| 後端類專案（Go/Python/Node.js 服務） | `references/backend-testing-context.md` |

---

## 定位說明

此 skill 與同主題層級的正交性（定位依據：三者職責不重疊）：

| 層級 | 職責 |
|------|------|
| `test-assertion-design` skill（本檔） | 斷言內容設計的判斷概念（驗什麼、設計是否合理），跨語言通用 |
| `tdd` skill | TDD 流程管理（Red/Green/Refactor 階段推進） |
| `dart-test-async-guardian` skill | 非同步資源清理的生命週期防護（清理洩漏，非斷言設計） |
| `.claude/rules/core/test-assertion-design-rules.md` | 本專案（Chrome Extension/JS/Jest）專屬規則，含具體精度數字與目錄規定 |

---

版本紀錄在同目錄的 `CHANGELOG.md`。

