speckit-to-tc
⚙️ 執行前先讀
modules/config-loader.md。 啟用條件:config.speckit.enabled = true。
💡 第一次聽到 Spec Kit / SDD? 先看
concept-zh.md中文入門導讀(5 分鐘搞懂「為什麼規格寫好可以一鍵變 TC」)。
適用場景
- ✅ Jira 上一個「spec 規格制定」ticket 剛 close
- ✅ 使用者手上有一份
spec.md/api.md,想快速產第一稿 TC - ✅ 從規格 docx / wireframe 提煉 description 後想轉 TC
不適用場景
- ❌ spec 仍未定稿(要等 ticket close / spec freeze 後才跑)
- ❌ 純自動化腳本生成 → 用
test-automation - ❌ 已有完整 TC、想升級 → 用
test-review+test-master
Phase 1: 取得 spec 來源
依 argument 類型判斷輸入:
| 輸入 | 動作 |
|---|---|
Jira 票號(如 {{JIRA_PROJECT_KEY}}-XXXX) |
用 mcp__atlassian__getJiraIssue 或 curl + Atlassian PAT 抓 description |
本地 spec 檔(如 <repo>/feature/spec.md) |
用 Read 直接讀 |
| ticket URL | 從 URL 抽 key 然後同上 |
| 沒給 → 互動式詢問 | 「請給我 ticket key / spec 檔路徑 / 直接貼 spec 內容」 |
抓 Jira description 的標準 curl:
curl -s -G "{{JIRA_INSTANCE_URL}}/rest/api/3/issue/<KEY>" \
--data-urlencode "fields=summary,description,parent,status,assignee,attachment" \
-u "$ATLASSIAN_EMAIL:$ATLASSIAN_TOKEN" \
-H "Accept: application/json"
處理 ADF 格式 description:Atlassian description 通常是 Atlassian Document Format JSON。先轉成 markdown/plain text 再給後續分析。簡易處理:遞迴拉 text 欄位。
Phase 2: 功能歸位(決定輸出路徑)
從 config.speckit.feature_routing 讀路徑對應規則:
{
"speckit": {
"enabled": true,
"repo_root": "~/Desktop/your-spec-repo",
"feature_routing": [
{ "keywords": ["集章", "stamp", "NFC"], "path": "love/stamp/", "epic": "{{JIRA_PROJECT_KEY}}-XXXX" },
{ "keywords": ["健康", "步數", "health", "HealthKit"], "path": "peace/health/", "epic": "{{JIRA_PROJECT_KEY}}-YYYY" },
{ "keywords": ["錢包", "wallet", "payment"], "path": "love/wallet/", "epic": "{{JIRA_PROJECT_KEY}}-ZZZZ" }
],
"fallback": "ask_user"
}
}
依 summary / description 關鍵字 match feature_routing[].keywords,決定 <repo_root>/<path> 為輸出目錄;都不 match → 跳出問使用者。
檔案命名:tc-be-{KEY}-draft.md(如 tc-be-{{JIRA_PROJECT_KEY}}-1234-draft.md)
狀態 metadata:Draft v0.1 — pending review
Phase 3: 讀既有上下文(Cross-reference)
必讀(如存在):
- 同目錄
spec.md(產品規格) - 同目錄
api.md(API 契約) - repo 根
tc-index.md(命名規則 + Drive folder + 既有 TC) - 同目錄已上 Sheet 的 TC markdown
讀完之後應該知道:
- 這個 ticket 對應哪個功能模組
- 既有 spec / api 已涵蓋什麼
- 之前該團 TC 用過什麼 ID 命名規則
- 該團是 Web / Native / Flutter / BE-only?
Phase 4: 草擬 TC
結構(14 欄 A-N,跟通用模板對齊)
| 欄 | 名稱 | 範例值 |
|---|---|---|
| A | ID | BB-{FEATURE}-001 / WB-{FEATURE}-W001 |
| B | Phase | Feature Done |
| C | 測試結果 | Not Run |
| D | 測試結論 | (留空) |
| E | 測試標題 | 「批次上傳 PNG 檔名對應 ID 成功」 |
| F | 測試分類 | 9 種黑箱 / 6 種白箱(見下) |
| G | 優先度 | P0 / P1 / P2 |
| H | 平台 | Web / iOS / Android / Both / BE-only |
| I | 前置條件 | 「CMS 已登入;批次包 ZIP < 10MB」 |
| J | 步驟 | 編號列點 |
| K | 預期結果 | 可驗證,不能寫「應該正確」 |
| L | 自動化建議 | Y / N + 工具 |
| M | 備註 | 對應 spec 章節 / pytest test_name |
| N | 留空 | (Sheet 用) |
黑箱 / 白箱判定原則(分類鐵律,下面 9+6 種分類都要服從這條)
- 黑箱(BB):前置條件、步驟都必須是一般使用者看得懂、操作得到的——不需要任何第三方工具查看或測試(不用 Postman/curl/adb/Charles/mitmproxy/Instruments/Xcode Debug/資料庫直查/log 檢視等)。
- 白箱(WB):只要是API 相關測試,或需要用到第三方工具才能執行/驗證的,都歸類白箱。前置條件跟步驟都要明確寫出用什麼工具測試。
- 判定順序:先問「一般使用者不靠任何工具,照著步驟能不能重現、看得懂前置條件?」——能 → 黑箱;不能(需要工具介入或屬 API/內部狀態層級)→ 白箱。
- 為什麼要固定:這條分類標準跟 spec 內容脫鉚,spec 中途修正時只需要新增/調整對應 TC 內容,不需要重新判斷既有整份 TC 的黑白箱歸屬。
- 下面兩組分類是這條原則的具體案例化(例如「效能」黑箱角度是使用者感知/loading秒數、白箱角度是 cold start/TTFB 需工具量測),遇到不在清單內的新案例時回到上面的判定順序自行判斷,不要卡住。
⚠️ 反漂移規則:下面 9+6 種是「思考用的覆蓋checklist」,不是可以直接寫進 Column F 的值
這點很重要,2026-07-17 發現既有 Sheet 已經因為這個混淆漂移出至少 9 個未受管理的分類(含「邊界測試」vs「異常/邊界測試」這種近似重複):下面 9 種黑箱 / 6 種白箱是幫你想「這個功能該覆蓋哪些測試角度」的概念清單,但實際寫入 Google Sheet「測試分類」欄(Column F)的字串,只能是 config.test_case_format.categories 這個固定白名單裡的值(目前黑箱只有 3 種:冒煙-Feature Done / 功能測試 / 異常/邊界測試;白箱 6 種:API 驗證測試 / 內部狀態驗證 / 並發安全測試 / 記憶體測試 / Sentry 診斷測試 / JS Bridge 測試),或目標 Sheet 現有出現過的值。
映射規則:
- 黑箱概念分類 4~9(錯誤處理/生命週期/跨平台相容性/端對端/效能/a11y)在固定清單裡沒有對應分類時,force-fit 進「功能測試」或「異常/邊界測試」(依內容判斷哪個更貼近),不要另創「相容性測試」「端對端測試」「無障礙測試」這種新名詞。
- 白箱概念分類的「效能基準」「安全」若無法對應到既有的「Sentry 診斷測試」「JS Bridge 測試」等分類,同樣 force-fit 進語意最接近的既有分類(例如並發/資源類 → 並發安全測試或記憶體測試)。
- 用備註欄(Column M)保留真實測試意圖(例如寫「效能角度:冷啟動時間」),不要犧牲精確度去硬套分類——分類欄要固定不變,細節放備註。
- 每次要寫入既有 Sheet 前,先讀該 Sheet「測試分類」欄現有值當有效範圍;若真的判斷需要擴充固定清單,要先跟使用者確認,並同步更新 config + Sheet
statustab 的統計公式,不能悄悄新增。
黑箱分類(9 種思考角度,每類 N 條依風險評估——寫入 Sheet 時仍要套上面的反漂移規則)
- 冒煙-Feature Done:F1/F2/F3/F4 四階段 smoke
- 功能測試:happy path / 變體
- 異常/邊界測試:空值 / 超長 / 特殊字元 / 大檔
- 錯誤處理:401 / 403 / 500 / 網路斷
- 生命週期:背景前景切換 / 殺 App / 殺 process
- 跨平台 / 相容性:OS 版本 / 機型 / 主流瀏覽器
- 端對端:跨模組整合
- 效能(黑箱角度):使用者感知(loading 不過 N 秒)
- a11y:字級放大 / VoiceOver / TalkBack / 對比 / 觸控目標 / Reduce Motion
白箱分類(6 種)
- API 驗證:endpoint / status code / schema / 邊界
- 效能基準:cold start / TTFB / 60fps
- 安全:未授權 / token 偽造 / SQL inject / XSS
- 記憶體:leak / OOM / image cache 上限
- 並發:race condition / TSAN / Isolate 安全
- 內部狀態:狀態機 / 快取一致性
a11y 強制 4 條(每份 TC 都要)
若
config.workflow.auto_a11y_pairing = true才強制。
- 字級放大 iOS(Dynamic Type 最大)
- 字級放大 Android(fontScale 最大)
- VoiceOver / TalkBack 讀取順序
- 觸控目標 ≥ 44×44 pt / 48×48 dp + 對比度
BE-only 功能特化
如果 ticket 是 BE API(如「[BE][CMS] 基礎 API」),白箱占比拉高:
- BB 30% / WB 70%
- 平台欄全
BE-only - 自動化建議全
Y(套 pytest-api-kit) - 對齊
tc-to-pytestskill
Phase 5: 寫檔
- 寫到
tc-be-{KEY}-draft.md,放對應目錄(依feature_routing決定) - 開頭 metadata block:
---
ticket: {{JIRA_PROJECT_KEY}}-XXXX
spec_source: <repo>/feature/spec.md (§3 入口頁)
draft_version: v0.1
draft_date: 2026-MM-DD
status: pending review
output_target: Google Sheet(待人工搬上去)或 mode=markdown-only 下保留 .md
generated_by: speckit-to-tc skill
---
- 兩段:
## Black-box (BB)+## White-box (WB),每條 TC 用 markdown table - 最後一段
## 設計依據列出參考的 spec 章節
Phase 6: 後續建議(stdout 印給使用者)
✅ 草擬完成 → tc-be-{{JIRA_PROJECT_KEY}}-XXXX-draft.md
- BB N 條(其中 a11y N 條)
- WB N 條(其中 BE API 驗證 N 條)
- 主要 cover:[列 3-5 個 highlight]
- 未 cover / 不確定:[列 spec 沒講清楚的議題]
下一步建議:
1. 你 review 草稿(uncovered 議題回 PM 釐清)
2. 跑 test-review 對草稿打分(找 critical/major 缺口)
3. 通過後人工搬到 Google Sheet(命名照 tc-index.md 規範)
4. 對應 BE API 部分跑 tc-to-pytest
⚠️ 安全護欄
- ✅ 只 Write 到
tc-be-{KEY}-draft.md,不動其他檔 - ❌ 不主動上 Google Sheet(draft only,使用者手動搬,或啟用
sheet-md-sync自動同步) - ❌ 不主動 commit / push(draft 留著等 review)
- ❌ 不要編造 spec 沒寫的功能(uncovered 就標 uncovered)
- ⚠️ ADF 解析失敗時 fallback to plain text 而不是亂猜
配套整合
- 跑完後使用者通常會手動跑
test-review(自動)或test-master --mode=deep(升級) - 要把草稿正式上 Sheet → 用
sheet-md-syncskill(如已建) - BE API 部分要轉 pytest → 用
tc-to-pytestskill
設定依賴
| 設定 Key | 用途 | 缺值時行為 |
|---|---|---|
speckit.enabled |
啟用此 skill | skill 不啟用 |
speckit.repo_root |
草稿輸出 repo root | 互動式詢問 |
speckit.feature_routing |
功能歸位規則 | fallback 詢問使用者 |
jira.instance_url |
抓 Jira ticket | 改用 spec 檔路徑 |
workflow.auto_a11y_pairing |
a11y 強制 4 條 | 改為可選 |
範例
詳見 examples.md