BridgeCraft logobridgecraft
週報作品集關於聯絡登入
聯絡

bridgecraft

從資料視覺化到 AI Agent,一直在找下一個 meta

文章主題指南週報Labs作品集系統架構關於聯絡RSS

© 2026 BridgeCraft — Waiting7777. All rights reserved.

← 所有文章

你的 100% Coverage 是假的 — 用 test-audit 抓出沒被真正測到的分支

2026年10月20日 · Waiting7777 · 3 分鐘閱讀

自動化測試開發者工具
📂 自動化測試 系列📂 開發者工具 系列

問題在哪

Coverage 這個指標有一個根本性的問題:它只告訴你「這行有沒有被執行到」,不告訴你「這個行為有沒有被驗證」。

舉個例子,你有一個 function 長這樣:

export function parseConfig(raw: string | null) {
  if (!raw) return null;
  try {
    const config = JSON.parse(raw);
    return config.enabled ? config : { ...config, enabled: false };
  } catch {
    return null;
  }
}

這裡有四條路徑:raw 是 null 的 early return、parse 成功且 enabled 為 true、parse 成功但 enabled 為 false、parse 失敗的 catch。

現在寫一個 test:

test("parses valid config", () => {
  expect(parseConfig('{"enabled":true}')).toEqual({ enabled: true });
});

跑完 coverage,這個 function 大概顯示 60-70% line coverage。數字看起來不差,但其實只測了一條 happy path。null 的情況?沒測。JSON parse 失敗?沒測。enabled 是 false 的邏輯?也沒測。

這個問題在 AI 產 code 的時代特別嚴重。Copilot、Cursor、Claude Code 都很會生 code,也很會生 test——但生出來的 test 往往只驗證「正常情況下能跑」,error path 和 edge case 經常被跳過。你看到 coverage 是綠的,心裡覺得「應該 OK 吧」,結果 production 一遇到 null 就炸。


test-audit 做什麼

test-audit 是我做的一個 CLI 工具,專門解決這個問題。它交叉分析兩組資料:

  1. AST 靜態分析 — 用 TypeScript Compiler API 掃你的 source code,抽出每個 exported function 的分支結構:if/else、try/catch、switch/case、early return、ternary
  2. Istanbul coverage JSON — 讀 vitest 或 jest 跑出來的 coverage 數據

兩邊比對之後,告訴你哪些 function 的哪些分支「表面上被執行了但其實沒被真正測到」。

用法很簡單:

# 先跑你的 test 產 coverage
npx vitest run --coverage

# 再跑 audit
npx test-audit

輸出長這樣:

test-audit report

src/utils/parseConfig.ts
  parseConfig()        ⚠️  1/4 branches covered
    ├─ ✅ if/else → line 3
    ├─ ❌ early return → line 2
    ├─ ❌ try/catch → line 4
    └─ ❌ ternary → line 5

src/hooks/useAuth.ts
  useAuth()            ❌  1/4 branches covered
    ├─ ✅ if/else → line 10
    ├─ ❌ try/catch → line 15
    ├─ ❌ early return → line 20
    └─ ❌ switch → line 25

src/utils/formatDate.ts
  formatDate()         ✅  3/3 branches covered

Summary: 5/11 branches covered (45%)
         2 functions need attention

一眼就能看出哪些 function 需要補 test。


技術實作

整個工具的核心就三塊。

AST Analyzer — 用 ts.createSourceFile 解析 TypeScript(也吃 JavaScript),走訪 AST 找出所有 exported function(包含 export function 和 export const xxx = () =>),然後對每個 function 內部掃分支節點。判斷邏輯不複雜:

  • ts.isIfStatement → 有 else 就是 if,沒 else 且 then block 只有 return 就是 early-return
  • ts.isTryStatement → try-catch
  • ts.isSwitchStatement → switch-case
  • ts.isConditionalExpression → ternary

每個分支記錄 type 和 line number。

Coverage Reader — Istanbul coverage JSON 的結構其實很直觀:每個檔案有一個 branchMap 記錄所有分支的位置,b 記錄每個分支每條路徑的執行次數。把這兩個 map 解析出來就好。

Branch Matcher — 拿 AST 分析出的分支 line number,去 coverage 的 branchMap 裡找對應的 entry,然後看那個 entry 的所有路徑是不是都有被執行過(counts 都 > 0)。只要有一條路徑是 0,就標記為 uncovered。

整個工具零 LLM 依賴,純靜態分析。不需要 API key,不需要連網,速度快,CI 裡跑完全沒問題。


CI 整合

加一行就能在 CI 裡擋住假覆蓋:

- name: Audit branch coverage
  run: |
    npx vitest run --coverage
    npx test-audit --fail-under 80

--fail-under 80 意思是 branch 覆蓋率低於 80% 就 exit 1,PR 直接擋下來。

也支援 JSON 輸出,方便串接其他工具:

npx test-audit --format json

為什麼不用現有工具

你可能會問:Istanbul 本身不是就有 branch coverage 嗎?有,但它的粒度是「這個 branch 的 if/else 兩條路有沒有都走過」,不會告訴你「這個 function 整體的分支覆蓋狀況」,也不會用 function 為單位彙整給你看。

test-audit 做的事情是把 AST 層面的「這個 function 有幾個分支點」跟 coverage 層面的「哪些路徑被走過」交叉比對,然後用 function 為單位產出報告。你一眼就知道哪個 function 需要補 test,而不是盯著一堆紅紅綠綠的行號自己推理。


老實說

這個工具目前的 scope 刻意收得很窄:只看 exported function、只分析五種分支類型、只吃 Istanbul JSON。沒有 React component 層級的分析,沒有自動產 test,沒有 LLM 整合。

我覺得一個 CLI 工具最重要的是「跑一次就知道問題在哪」,而不是「什麼都能做但每次都要設定半天」。之後如果真的需要,再往 VS Code extension 或更細的分析擴展。

source code 在 GitHub,歡迎開 issue 或 PR。

— BridgeCraft,2026

每週一篇 — 技術趨勢背後的商業邏輯

分享:

Waiting7777

WoW Arena 冠軍轉前端,用電競 meta 思維拆解技術趨勢。

關於作者

相關文章

Orca 七個月拿下 10 萬顆星:我拆了它的 GitHub 數據,看到 agent 開發真正的瓶頸AI Agents開發者工具+1

Orca 七個月拿下 10 萬顆星:我拆了它的 GitHub 數據,看到 agent 開發真正的瓶頸

一個由 agent 寫出來、拿來管 agent 的開源 IDE。19,000 個 commit、979 次 release 背後,最值得看的數字是 2,525 個放了一個月還沒人處理的 PR。

2026年10月20日 · Waiting7777 · 7 分鐘閱讀

繼續閱讀 →
跑了兩週 Agent QA Pipeline — 真實數字、踩到的坑、重來我會怎麼做AI Agents自動化測試+1

跑了兩週 Agent QA Pipeline — 真實數字、踩到的坑、重來我會怎麼做

這是 post-mortem,不是 case study。做對的三件事、做錯的三件事、以及為什麼這套東西接下來要抽成 `claude-qa-pipeline` OSS。

2026年10月20日 · Waiting7777 · 6 分鐘閱讀

繼續閱讀 →
我用 15 個 Claude Code Agent 跑了一條自動 QA Pipeline — 兩週 17 個 merged PRAI Agents自動化測試+1

我用 15 個 Claude Code Agent 跑了一條自動 QA Pipeline — 兩週 17 個 merged PR

這不是 proof of concept,是跑在 macOS launchd 上的真實系統:每天兩班、spec-driven、自己開 Linear issue、自己發 PR、自己從過去的 fix 裡學新的 pattern。

2026年10月20日 · Waiting7777 · 5 分鐘閱讀

繼續閱讀 →

這篇文章對你有幫助嗎?

每週一篇 — 技術趨勢背後的商業邏輯

AI 產業在變什麼、工程師該注意什麼——拆清楚寄到你的信箱。