Skip to content
Back to skills

Browser Qa

ASecurity

瀏覽器功能測試方法論。當要對某功能 / 頁面 / 流程做功能測試時觸發——含「開發完成需驗證新互動 / 新畫面 / 新流程」, 也含使用者說「執行 / 跑 / 做 一些測試案例」、「幫我測這個功能」、「跑 e2e / 端對端測試」、「回歸測試」、 「測試落地 / 沉澱測試 / 存測試案例」等意圖(這些都指「設計並執行功能測試、沉澱成可重跑 runner」,不是單純跑一支既有腳本)。

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 3, 2026
testingpythonsqlapi

Works with

  • claude code
  • api
  • mcp

Security analysis

A100/100

Pro scans all 5 files and shows the line behind each finding

Scanned September 28, 2026

npx -y skills add abs1294/fulin-claude-plugins --skill browser-qa --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Browser Qa?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Browser Qa
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/abs1294-browser-qa/badge)](https://www.skillsdirectory.com/skills/abs1294-browser-qa)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: browser-qa
description: >
  瀏覽器功能測試方法論。當要對某功能 / 頁面 / 流程做功能測試時觸發——含「開發完成需驗證新互動 / 新畫面 / 新流程」,
  也含使用者說「執行 / 跑 / 做 一些測試案例」、「幫我測這個功能」、「跑 e2e / 端對端測試」、「回歸測試」、
  「測試落地 / 沉澱測試 / 存測試案例」等意圖(這些都指「設計並執行功能測試、沉澱成可重跑 runner」,不是單純跑一支既有腳本)。
---

# Browser QA Skill

兩階段皆由 QA agent(qa-engineer)一手包:設計測試計畫(含 critical points)→ 預擬 codify 草稿
(grep 原始碼填真實值)→ 首跑收失敗清單 → 只對失敗 CP 定向探索補值,以結構化證據
(API 碼 / DOM 讀回 / 來源 readback)自我驗證並輸出測試報告;主 Agent 只派工收結論、不親跑 MCP。

> **機械保證的邊界(先讀)**:本 skill 分兩層——
> **產物層**(每個功能在 `tests/e2e/` 留下可重跑的 `test_*.py` + junitxml 報告 + 情境登記〔三層:`<模組>/COVERAGE.md`;舊版:catalog〕)由 `qa-flow.sh` 強制。Stop hook 與 `project-knowledge-gate` 只在 qa-webwright plugin 已啟用的專案生效;只以 symlink 取用本 skill 時這兩道閘不存在,完成判準改由下方執行清單的 #5、#8 自行對照。
> **設計品質層**(覆蓋矩陣是否窮盡、證據是否夠強、是否真走兩階段 qa-engineer 設計)**無法機械強制**(品質是 AI-complete)——下面的方法論是**強烈建議的流程**,靠引導不靠閘門。
> 所以:產物一定會有,但「測得好不好」需人把關。別把「hook 全綠」當成「測試設計到位」。

把測試計畫的每條「預期結果」對映成一個 **critical point**,再落成可重跑 runner 裡**(至少)一行 `assert`**(雙向卡控等可多行)。

這條設計的好處:測試**寫一次**(探索階段花一次 agent token),之後直接 `pytest`(或對應 runner)跑——
有 assert 就能自動判 pass/fail、無 agent、不花 token、可掛 CI。

> **方法論中立、載體固定優先 pytest(核心原則)**:本 skill 的價值在「測試設計方法論」(覆蓋矩陣 /
> 可追溯 / CP→assert / 必測 checklist / 測試資料原則)。沉澱載體**固定優先 pytest-playwright**——
> **唯二例外**:(a) 目標專案「既有」測試資產就是別的 runner(如既有 Playwright JS 專案)→ 沿用既有、對齊風格;
> (b) greenfield 且**使用者明確不同意**裝 Python 環境 → 退而用 Playwright JS。除此之外一律 pytest,
> **不得因「載體中立」自行選 JS**(歷史踩雷:執行者看到子目錄有 JS 專案就鑽進去出 JS)。
> 判定一律靠**結構化證據**(API 業務碼、DOM/a11y 讀回、來源 readback),**不靠讀截圖**。截圖至多留檔備查。
>
> **落點鎖死**:測試 / 報告 / catalog 一律落在**你起 session 的那個資料夾**底下(`tests/e2e/`),
> **禁止鑽進子專案目錄**。此規範由 `qa-flow.sh`(鎖 `CLAUDE_PROJECT_DIR`)機械執行,見下方「qa-flow.sh 腳本」。

| Phase | 執行者 | 職責 |
|-------|--------|------|
| Phase 1 | QA Agent(本 plugin 的 `qa-engineer` agent) | 設計測試計畫、定義 critical points 與輸出格式 |
| Phase 2 | QA Agent(同一個 `qa-engineer` agent 接續執行) | 預擬草稿(每 CP 一行 assert)→ 首跑收失敗清單 → 定向探索補值 → 結構化證據自驗 → 輸出測試報告 + 回填 catalog |

> 主 Agent(指揮官)不出現在任何 Phase:它只判斷何時該 QA、派 qa-engineer agent(附環境啟動方式 /
> 已知 DOM 坑 / allow-list 前提)、收報告結論,**不親跑 MCP**。實作 agent 不做瀏覽器自驗。
> **allow-list 前提**:qa-engineer 是 sub-agent、無法互動回應 permission prompt——要用的
> `mcp__playwright__browser_*` 工具必須已在專案 `settings.json` / `settings.local.json` 的
> `permissions.allow`,否則會被 deny(跨專案使用本 plugin 時先確認這件事)。

## 派工範本(主 Agent 派 qa-engineer 用)

派 `qa-engineer` 時,派工單(Agent/Task 的 prompt)**照下方範本逐格填寫**。專案 `tests/e2e/qa-webwright.json` 有 `dispatch_gate` 段時,
`hooks/guard-qa-dispatch.js` 會在派工當下檢查這幾格(缺一即 deny,一次列完所有缺項);沒有該段時不檢查,但照填一樣是好派工單。
每一格為什麼要寫:派工單上沒寫的那一格,QA 就不會測、不會問——範圍完整性是指揮官的責任。

| 格 | 閘怎麼驗(只驗有沒有表態,不判內容對錯) |
|---|---|
| 首行回報指示+「本任務由你親自執行,不得再轉派」 | 出現「親自執行/不得再轉派」字樣(回報鏈固定一跳) |
| 【開工前必讀】 | `dispatch_gate.required_reading` 列的路徑都出現在派工單(斜線方向、大小寫不拘;預設只要求專案裡真的存在的檔) |
| 【增量分流】 | 該格第一行明選 `reuse`(附要改的既有 test 檔路徑)或 `新TC`(附一句為何既有案例接不住)——見 Phase 1「增量分流」 |
| 【目標環境】 | 該格不是空白、不是範本佔位(本機預設填一行 localhost 即可) |
| 【測試資料來源】 | 第一行開頭寫「選 a」「選 b」或「選 c」(固定格式,其他寫法不算表態);理由與證據只讀「作答段」(第一行起到空行,或到 a./b./c./(/⛔ 開頭的說明行為止);選 b、c 必附理由。a=走真實業務流程長出來(常態,不論成本)、b=封閉例外(只限產品外部系統產生、產品端沒有入口的前置;理由要點名是哪一類外部系統邊界,並附產品端證據的「檔名:行號」)、c=依賴既有資料(僅限字典/設定類) |
| 【範圍外發現】 | 要求 QA 把範圍外看到的異常列在報告「範圍外發現」節回報 |
| 【開工前對齊】 | 該格寫了對齊結論或「無分岔+理由」(不是空白、不是範本佔位) |
| 【範圍展開】 | 四格都寫到:正向/反向(終止分支)/狀態序列/共用元件;任一格填「無」附理由 |
| 【欄位級驗證】 | 寫出要拿什麼實值比對(DB 讀回/三方對照);「畫面有顯示」「回 200」不算 |

範本(`<…>` 換成實際內容;刪掉角括號):

<!-- qa-dispatch-template:begin -->
```text
完成後把測試報告(含「範圍外發現」節)回報給主對話。本任務由你親自執行,不得再轉派給其他 agent。
【任務】<要測的功能/變更範圍;使用者原話照貼>
【開工前必讀】<照 tests/e2e/qa-webwright.json 的 dispatch_gate.required_reading 逐條列路徑;另外一律寫出 CLAUDE.md(專案概要)、CONTEXT.md(專案用語)、tests/Project_Detail/PROJECT.md,專案沒有的寫「<檔名>:專案沒有這個檔」>
【增量分流】<reuse 或 新TC 擇一寫在最前面>:<reuse 寫要改的既有 test 檔路徑;新TC 寫一句為何既有案例接不住>
【目標環境】<前端網址;後端 API/登入身分來源與預設不同時一併寫>
【測試資料來源】<a、b、c 三選一,寫成「選 X」;a=走真實業務流程長出來(常態,不論成本);b=封閉例外,只限產品外部系統產生、產品端沒有入口的前置(外部簽核回呼/上游推送/外部主檔 mock/目錄服務),理由寫出是哪一類,並附產品端守門或寫入點的「檔名:行號」當證據;c=依賴既有字典/設定類,附理由;理由與證據寫在同一段,空行之後的內容不算>
【開工前對齊】<對齊結論一句話;或「無分岔:<一句理由>」>
【範圍展開】<1 正向:…;2 反向(退件/拒絕/取消/軟刪/逾時/重送/權限不足,逐條列適用與否,不適用說為什麼):…;3 狀態序列(做A→做B→撤銷A→存檔→重開):…;4 共用元件(本次觸及的共用元件與其他使用點是否連帶回歸):…>
【欄位級驗證】<涉及 N 個欄位;逐欄比對畫面顯示值 ↔ API 回傳 ↔ DB 實值;寫入型逐欄讀回 DB(bool/int 用非預設值、集合驗筆數+順序);不驗的欄位逐個列理由>
【範圍外發現】範圍外看到的異常一律列在報告「範圍外發現」節回報,不自行擴大修改、也不當作沒看到。
【驗收條件】browser-qa SKILL.md「執行清單(完成判準)」8 項全過;<本次功能行為條款,逐條可觀察>
【回報格式】已讀清單(逐檔列出實際讀過的開工前必讀檔案,沒讀的寫理由,例如專案沒有這個檔)/測試報告路徑/範圍展開四格逐格結果/範圍外發現/codify 的測試檔與實跑輸出
【執行方式】本任務由你親自執行,不得再轉派。照 browser-qa SKILL.md「執行清單(完成判準)」核對 8 項;每次呼叫 qa-flow.sh 都帶 CLAUDE_PROJECT_DIR=<Primary working directory>。完成後回報主對話。
```
<!-- qa-dispatch-template:end -->

填好的樣子(此例可一次過閘;`hooks/test-gate.mjs` 會拿這段實跑驗證):

<!-- qa-dispatch-example:begin -->
```text
完成後把測試報告(含「範圍外發現」節)回報給主對話。本任務由你親自執行,不得再轉派給其他 agent。
【任務】測 https://shop.example.test 的購物車:加入商品、移除商品、購物車徽章數量、結帳前明細
【開工前必讀】CLAUDE.md(專案概要)、CONTEXT.md、tests/Project_Detail/PROJECT.md
【增量分流】新TC:tests/e2e 還沒有購物車的既有案例(CATALOG 查無),既有案例接不住
【目標環境】https://shop.example.test(公開測試站;帳號用站方公開的測試帳號)
【測試資料來源】選 a,理由:購物車內容由 UI 加入商品自然產生,走真實流程即可
【開工前對齊】無分岔:需求就是驗購物車既有的四個操作,沒有「做成什麼樣」的解讀分岔
【範圍展開】1 正向:加入商品→徽章數量+1→明細列出該商品;2 反向:移除最後一件後徽章消失、明細顯示空狀態;結帳途中取消回到購物車;權限不足不適用(公開站只有一種角色);3 狀態序列:加入 A→加入 B→移除 A→重新整理→確認只剩 B 且數量正確;4 共用元件:購物車徽章也出現在頁首,頁首數字一併驗
【欄位級驗證】明細 4 個欄位(品名/單價/數量/小計)逐欄比對畫面顯示值與購物車資料的實值;公開站查不到 DB,實值以站方回傳的購物車資料為準
【範圍外發現】範圍外看到的異常一律列在報告「範圍外發現」節回報,不自行擴大修改、也不當作沒看到。
【驗收條件】browser-qa SKILL.md「執行清單(完成判準)」8 項全過;四個操作後徽章數量與明細逐欄一致
【回報格式】已讀清單(沒讀的寫理由)/測試報告路徑/範圍展開四格逐格結果/範圍外發現/codify 的測試檔與實跑輸出
【執行方式】本任務由你親自執行,不得再轉派。照 browser-qa SKILL.md「執行清單(完成判準)」核對 8 項;每次呼叫 qa-flow.sh 都帶 CLAUDE_PROJECT_DIR=/path/to/project。完成後回報主對話。
```
<!-- qa-dispatch-example:end -->

被閘擋下時:照 deny 訊息把**所有**列出的缺項一次補齊,重發**同一個** agent;不要改派其他 agent type 繞過。
專案要加檢查(如【開工前對齊】【範圍展開】或自訂 regex)改 `dispatch_gate.checks`/`custom_checks`,範本也要同步加格(加閘沒同步範本=照範本寫仍被擋)。

本 skill 分層維護:
- **方法論** `methodology/` — 怎麼做測試,穩定、不綁技術棧。
- **知識庫** `knowledge/` — 踩過的雷與領域知識,**會長大**、依專案技術棧選用。

---

## 前置(一次性 / 每次)

**一次性(每台開發機):**
- 沉澱 runner **固定優先 pytest-playwright**(例外見上方核心原則)。**不需自己 mkdir / 判斷落點**——
  Phase 2 第一步一律先跑 `qa-flow.sh bootstrap`,它會盤點既有資產、發安裝決策訊號、鎖定落點。
- 探索方式優先用專案既有手段(Playwright MCP 的 a11y snapshot `ref`、Page Object)。

**選用(僅「真實外部站」備用探索):**
- 當未來需打**真實外部站**(無法注入 a11y test token、後端不可攔、`ERR_HTTP2_PROTOCOL_ERROR`/Akamai/H2
  封鎖 Chromium、長程未知路徑)時,才裝 **webwright**(`/plugin install webwright@webwright` +
  `playwright install firefox`,用其 SOTA 自主探索)。**探索完一律 codify 成上述 runner,回歸端永遠不是 webwright。**
  (`ERR_HTTP2_PROTOCOL_ERROR`/指紋封鎖的處置見 `knowledge/pitfalls.md` H 段:先換 `playwright.firefox`。)
  本機自家系統(有 a11y、有後端可攔)**不需要**裝 webwright。

**每次測試前:**
- **專案 QA 知識層(約定位置)**:`<CLAUDE_PROJECT_DIR>/tests/Project_Detail/`,入口 `PROJECT.md`。
  入口是**路由中心、分層負責**:只放專案鐵則與路由表,細節(環境啟動、UI 操作規範、領域驗證知識…)
  在同目錄分層檔,照路由**按需讀**、不整包灌。入口存在就**必先讀**(`bootstrap` 會回報 `PROJECT-KNOWLEDGE` 訊號);
  不存在而專案有專屬 QA 知識時,建議依此分層建立,別把專案知識寫進泛用 skill。
  「必先讀」由機械層執行:`hooks/project-knowledge-gate.js`(PreToolUse)在入口存在而未讀時 deny 瀏覽器呼叫
  (最多兩次、FAIL-OPEN),`qa-early-nudge` 同步軟提醒——先軟後硬。
- 目標專案要能在本機跑起來(啟動方式見該專案的 CLAUDE.md / README;Windows 背景啟動雷見 `knowledge/pitfalls.md` D 段)。

---

## Phase 1:設計測試計畫(QA Agent)

### 增量分流(reuse-first,設計前先做)

**設計任何新 TC 之前,先盤點既有測試資產**:專案已有 codified 測試套件時(含索引/情境正本,如 CATALOG、COVERAGE 這類檔案),先查「這次變更落在哪個模組、既有案例的導航與斷言點能不能到達」。二選一表態後才進設計:

- **reuse**:變更落在既有案例的 seam 內(改欄位/驗證規則/顯示邏輯)→ **直接改既有 runner**:加 assert/參數化,只跑受影響案例+同資料夾回歸——不開瀏覽器探索、不寫新 TC。既有腳本已內建登入、導航、seed,邊際成本只剩斷言,且斷言永久留在回歸網。
- **新 TC**:無既有覆蓋/新畫面/新互動、或需視覺判斷(排版、loading、console 紅字)→ 附一句理由(為何既有案例接不住),走完整 Phase 1→2。

一句話判準:**既有腳本能到達並斷言的行為,不重新探索**。新功能的主動探索情境紀律不因此豁免——它管新功能的未知未知,本節管小改的增量。

由 `qa-engineer` agent 負責,依 `methodology/test-plan-design.md` 設計,**輸出一律用固定的單一 TC 表**
(每列一條 TC,欄位:TC / 功能情境 / 操作步驟 / 證據 / 預期結果 / 需求;格式詳見 `qa-engineer` agent 的「輸出」段):

- **內部設計動作(不寫進輸出)**:窮舉覆蓋矩陣(狀態維度)確保每維度有 TC、大型功能做一次紅隊漏測複查補漏——
  補出來的 TC 直接併進表,矩陣與複查過程不另立段落。
- **可追溯**:每條驗收條件 / 需求點對應到表的「需求」欄;不測的另列寫「不測 + 理由」。

**關鍵交接規則**:每條 TC 的每個「預期結果」都要寫成「可由其結構化證據獨立驗證」的形式
—— 這就是 Phase 2 要列成的 critical point 清單、再落成 runner 的 assert。
詳見 `methodology/critical-points.md`。

---

## Phase 2:執行測試(QA Agent)

QA Agent(qa-engineer,接續 Phase 1 由自己執行)嚴格按測試計畫執行,不得自行增減步驟。流程是「**預擬 codify 草稿 → 首跑收失敗清單 → 只對失敗 CP 定向探索補值**」(draft-first:探索是補洞手段,不是起手式)。

### 執行清單(完成判準)

沉澱成可重跑的 runner 是本 skill 的目的,不要問要不要做;唯一要問的是 greenfield 時同不同意在這台電腦裝 pytest-playwright。

### 髒資料紀律(造資料的測試必守)

- **可識別**:測試造的業務資料(單據、名稱、標題類欄位)一律帶專案約定的測試前綴(無約定時用 `E2E-`)——含瀏覽器探索階段造的資料,殘留才能被機械定位。
- **自種自清**:造資料的 runner 必配 fixture teardown(`yield` 後清理,失敗也會執行)。「跑完整生命週期到終態」是首選(終態路徑本身有測試價值),但它扛不住測試中途失敗——teardown 是兜底,兩者並用。
- **收尾清掃**:大批執行結束後,用專案的殘留清掃工具(或按前綴查詢)確認無測試殘留,才算收工。
- **只刪自己造的**:teardown 用 `SCOPE_IDENTITY`/唯一前綴鎖定自己造的那幾筆,**不要 UPDATE 回原值**——那會把別人的資料改壞。

### ⭐ 五條硬規則:測試不得依賴環境既有資料(寫 assert 前必讀)

判準一句話:**把業務資料清空、只留 schema 與字典,這支測試仍該能跑通**。

① **前提資料自己生,走產品入口**(不寫死既有 Id/代碼;直接 INSERT 造出的形狀產品永遠不會產生)
② **期望值查來源推導,且不得抄被測程式那句查詢**(同源=後端錯時測試一起錯)
③ **定位錨語系無關**(產品既有錨 → i18n key 取譯文 → 測試端 setAttribute;⛔ 不得在產品碼埋測試專用屬性)
④ **沒資料不准 skip 要自己生**(A 資料缺→自造/B 環境→具名 skipif/C 結構變→改 fail/D 共用狀態被佔或前置沒做成功→改 fail;執行期 A/D 類 skip 由 conftest 掛點判整輪失敗)
⑤ **驗環境看 `response.url`,不信環境變數**(打錯後端=前四條做得再好也整輪作廢)

**五條的完整判準、理由與實測代價見 `methodology/critical-points.md`「五條硬規則」節——寫 CP 與草稿前讀那一節。**
⚠ ③ 特別注意:`assert xxx.get_by_text("送出").count() > 0` **是定位器不是斷言**,切語系一樣失效,別以為有 `assert` 就豁免。

8 項完成判準(可用任務清單工具追蹤進度,非強制;任一 CP self-verify 失敗〔#7〕時回到 #5/#6/#7 重跑):

```
#1 Phase2-0 qa-flow.sh bootstrap(盤點資產 + 鎖落點 + 回報登記模式 MODE)
#2 Phase2-0b 僅 greenfield 空目錄:問使用者「是否同意裝 pytest 環境」(不問要不要沉澱)
#3 Phase2-1 列 critical points 清單
#4 Phase2-2 預擬 codify 草稿:每 CP 先落 pytest assert(grep 原始碼填真實值,拿不到標 TODO-EXPLORE)
#5 Phase2-3 qa-flow.sh run(防假綠燈 grep + pytest --junitxml;首跑收失敗清單,修完重跑)
#6 Phase2-4 定向探索補值:僅對失敗 / TODO-EXPLORE 的 CP 做 MCP 探索修草稿(≤5 CP 一批,修完回 #5)
#7 Phase2-5 self-verify(逐 CP 對結構化證據 + FAIL 前排除紀律)
#8 Phase2-6 輸出報告 + qa-flow.sh catalog 登記每個情境(三層:<模組>/COVERAGE.md → 重生 CATALOG)+ qa-flow.sh audit 確認 drift 0/0/0
```

- **#5、#8 是硬性落地閘**:沒跑 `qa-flow.sh run` 出報告、沒跑 `qa-flow.sh catalog` 登記,**不得宣稱測試完成**。
  三層模式下 **codify 完成判準=drift 0/0/0**(孤兒/幽靈/佔位皆 0;每次 pytest 結束總結區會印 `COVERAGE drift clean` 或 `⚠️ COVERAGE DRIFT`)。
- **假綠燈紀律(draft-first 的代價)**:#4 預擬的 assert 是推測——**禁止為了轉綠而弱化斷言、寫恆真條件、或把 FAIL 的 CP 改成 skip**;失敗 CP 唯一的修法是 #6 探索取真實值。「修到綠就交」不是完成,self-verify(#7)照樣逐 CP 對證據。

### ⚡ qa-flow.sh 腳本(必用)

本 skill 提供 `qa-flow.sh`(位於本 skill 目錄)把「一定要落地的動作」包成 subcommand,落點一律鎖 `CLAUDE_PROJECT_DIR`(session 起始目錄),執行者(QA Agent)**不要自己 mkdir / 自己組 pytest 指令 / 自己判斷落點**。

> **落點鐵則**:`CLAUDE_PROJECT_DIR` Claude Code 不一定內建,故**每次呼叫 qa-flow.sh 都要顯式帶 `CLAUDE_PROJECT_DIR=<Primary working directory>`(原封不動、即環境說明裡的 session 起始目錄)**。
> **嚴禁自己 export 成子目錄**(即使判斷子目錄才是被測 repo 也不行)。你知道 Primary working directory 是哪,就用那個。
> 要測某子專案 → 請使用者到該子專案目錄重啟 claude,不要從上層鑽進去(`test-plan-design.md` §0 原則)。
> `qa-flow.sh run` 內建守門員:落點若不在 `CLAUDE_PROJECT_DIR/tests/e2e/` 正下方(鑽了子目錄)會直接報錯擋下。

| 指令 | 動作 | 對應步驟 |
|------|------|---------|
| `qa-flow.sh bootstrap` | 盤點既有測試資產(pytest/JS/空)、偵測登記模式 `MODE`(three-layer/legacy-catalog/three-layer-no-config/none)、發安裝/runner 決策訊號(不擅自安裝)、順手 audit | Phase2-0 |
| `qa-flow.sh scaffold <feature> <pytest\|playwright-js>` | pytest:三層骨架(複製工具進 `tests/e2e/tools/`+參數檔 `qa-webwright.json`+conftest 掛點+`<feature>/COVERAGE.md`);安裝指令只印出讓使用者跑 | Phase2-0b(使用者同意後)|
| `qa-flow.sh run <feature> <test-file> [date]` | grep 驗證 test 函式存在(防假綠燈)→ `pytest --junitxml` 出報告(sqlite 自動記錄;三層模式跑完重生 CATALOG)| Phase2-3(首跑收失敗清單+每輪修完重跑)|
| `qa-flow.sh catalog <情境> <函式> <狀態> <模組>` | 三層:寫進 `<模組>/COVERAGE.md`(函式可寫 `test_x.py::test_y`,以函式為主鍵 update/append)再重生 CATALOG;舊版:回填單一 catalog.md。寫入一律同目錄 tmp+原子 rename | Phase2-6 |
| `qa-flow.sh audit [--fix]` | 三層:drift_check(孤兒/幽靈/佔位,有漂移 exit 3);`--fix` 把孤兒補成「待補」佔位列,補完仍有漂移(佔位待寫情境、幽靈)照樣 exit 3,exit 0 才是 drift 0/0/0;舊版:catalog 孤兒列。非本 plugin 格式的 catalog 一律跳過 | Phase2-6 收尾 |
| `qa-flow.sh tools-sync [--force]` | 以 plugin 新版更新已複製的工具;專案端改過的只警告不覆蓋;參數檔永不覆寫 | plugin 升級後 |
| `qa-flow.sh migrate [--dry-run]` | 舊版 4 欄 catalog → 三層(列數對帳、舊檔改名保留) | 舊專案一次性 |

**bootstrap 決策訊號怎麼接:**
- `ASSET: pytest-existing` → 直接復用既有、對齊風格,進 Phase2-1。
- `ASSET: js-existing` + `ACTION-REQUIRED: ask-user-runner` → **問使用者**:在既有 JS 旁另起 pytest,或沿用 JS。
- `ASSET: none` + `ACTION-REQUIRED: ask-user-install` → **問使用者**是否同意裝 pytest-playwright:同意→`scaffold <feature> pytest`;不同意→`scaffold <feature> playwright-js`。

> **腳本不代裝任何東西**:安裝指令一律印出來由使用者執行(依決策:安裝需經同意)。

### 執行步驟

1. **列 critical points**:把測試計畫**每條預期結果**列成一張清單,每個 CP 要能被其結構化證據
   獨立驗證(讀取型一個即可;寫入/送出型需業務碼+readback;守門/卡控型斷言狀態或錯誤碼——證據強度依 CP 類型,
   見 `methodology/critical-points.md` 證據規範)——不依賴「我記得剛剛點了什麼」。

2. **預擬 codify 草稿(draft-first,不先開瀏覽器)**:直接把每個 critical point 落成 `tests/e2e/<feature>/test_<feature>.py`(三層;舊版專案為 `tests/e2e/test_<feature>.py`)裡
   **(至少)一行 `assert`**(雙向/多面卡控可對多行)——斷言打在結構化證據上(業務碼 `code=="0000"` 非只看 HTTP 200、
   DOM/a11y 讀回 unique token、DB/重查 readback)。寫入型操作必「寫 unique token → 讀回那一筆比對」,不可只驗送出成功。
   selector / 端點 / 欄位名 / 業務碼**先 grep 原始碼取真實值**——多數路徑落差是「程式碼真實值 ≠ 記憶」的問題,
   grep 就能填掉大半;grep 拿不到的(動態 DOM、跨頁流程、登入態相依)在該處標 `TODO-EXPLORE` 註記,別瞎猜。
   **草稿同時要滿足上方五條硬規則**:前提資料走產品入口自造(非寫死既有 Id)、期望值查來源推導(非字面數字)、
   定位錨語系無關(非中文顯示字)、沒資料時自造(非 skip)、開跑前驗 `response.url` 確認打對後端。
   斷言規範與五條硬規則的完整判準見 `methodology/critical-points.md`。

3. **Execute 首跑收失敗清單(用 `qa-flow.sh run`)**:跑 `qa-flow.sh run <feature> <test-file>`(date 可省略=今天)——
   它先 grep 驗證 test 函式確實寫入(防假綠燈),再跑 `pytest --junitxml` 出報告到 `tests/e2e/reports/<feature>-<date>.xml`
   (assert 失敗 → 非 0 exit)。**首跑的目的不是全綠**:是把「預擬猜錯 / TODO-EXPLORE」的 CP 變成明確的失敗清單,
   探索預算只花在這份清單上。最終綠燈那次的報告路徑回填報告模板「報告產物」欄;截圖至多留檔備查,不作判定依據。

4. **定向探索補值(只探失敗的)**:僅對失敗與 `TODO-EXPLORE` 的 CP 開 MCP 探索——**先 grep 原始碼再上 DOM**;
   a11y `ref` 比 CSS 文字選擇器精準。(僅「真實外部站、無 a11y、長程未知」才改用 webwright 自主探索,見前置。)
   **Context 經濟(必守,違反會把 session 撐到反覆 compact)**:全頁 snapshot 只在「導航後首次 / 結構變化後」拍,
   驗單一元素或讀值用 `browser_evaluate` / 既有 a11y `ref` 定向讀取;**批次修值**——探索一批 CP(建議 ≤5)
   → 立即回填草稿 → 回步驟 3 重跑,**禁止把全部失敗 CP 在 MCP 逐步跑完才開始回填**。細節與實測教訓見 `knowledge/pitfalls.md` I 段。
   **修草稿只准用探索到的真實值——禁止為了轉綠而弱化斷言或改 skip**(見上方假綠燈紀律)。全綠後進步驟 5。

5. **Self-verify**:逐項走 CP 清單,確認**每個 assert 的結構化證據明確相符**才打勾。
   任一 CP 失敗 → 診斷具體原因 → 修測試 → 重跑重驗。
   **判 FAIL 前先走 `methodology/test-plan-design.md` §7 的「FAIL 前排除紀律」**(服務存活 / 操作沒生效五排除 /
   業務語意三問),別把環境塌 / 探索沒對準 / by-design 卡控誤判成功能 FAIL。

6. **輸出測試報告(格式見下)+ 登記情境**:`qa-flow.sh run` 的防假綠燈 grep 已確認 test 函式存在
   (Write / replace 在並行取消時可能假成功,造成「假登記、假綠燈」——腳本已把關)。
   接著對**每個情境**跑 `qa-flow.sh catalog <白話情境> <test_x.py::測試函式> <完整/部分/未覆蓋> <模組資料夾>`
   登記到 `tests/e2e/<模組>/COVERAGE.md`(三層;舊版專案回填 `tests/e2e/catalog.md`),最後 `qa-flow.sh audit` 確認 drift 0/0/0
   (必做,見 `methodology/test-plan-design.md` §0.5、`methodology/test-asset-hygiene.md` §1)——讓 codify 閉環不止於 runner、累積成可查的跨功能應測情境索引。
   寫測試碼當下若被 `guard-test-asset-hygiene` hook 擋(exit 2),照訊息修掉新增的硬編/漂移/A/D skip 再繼續;
   合法例外用 `# SCAN-REVIEWED: safe — <理由>` 等註記宣告(總表見 plugin README「跳脫機制總表」),**不要**用 `--write-baseline` 把新增蓋章成存量。

### 測試哲學(通用,少數鐵則)

- **能走 UI 就走 UI**:模擬使用者操作要點畫面、填表、按鈕,不要繞過前端直接打資料來源
  (例外與細節見 `knowledge/pitfalls.md` A 段)。UI 上跑通才算 PASS。
- 排名語意(最新 / 最便宜 / 評價最高)要用畫面實際的排序/篩選控制,不能用自己對結果的排序。
- 數字 / 日期 / 數量 / 單位是**精確**比對。
- 技術棧專屬的「怎麼驗 / 怎麼點 / 哪裡有雷」一律查 `knowledge/pitfalls.md`,**不要靠記憶猜 UI**。

---

## 測試報告格式

```
## 測試報告
測試範圍:{功能} 測試日期:{YYYY-MM-DD} 報告產物:{runner 報告路徑,如 pytest junitxml / log;若有截圖留檔一併附}

### 結果摘要
| 測試案例總數 | PASS | FAIL |
|---|---|---|
| N | N | N |

### 案例明細
| 編號 | 功能 | 結果 | 證據(assert / API 碼 / readback 值) | 備註 |
|------|------|------|--------------------------------------|------|
| TC-001 | {功能} | PASS/FAIL | submit code=="0000" + DB 讀回 token 相符 | {若 FAIL 說明差異} |

### 發現問題(若有 FAIL)
BUG-{編號}|嚴重度:Critical/Major/Minor|對應 TC-{編號}
重現步驟 / 預期 / 實際 / 證據(assert 失敗訊息 / 實際 API 碼 / readback 值)

### 範圍外發現(派工範圍以外看到的異常;沒有就寫「無」)
現象 / 重現步驟 / 證據——只回報,不擴大修改

### 結論
通過 / 需修正後重測(列出 BUG 編號)
```

**每個 PASS/FAIL 都必須引用一行 assert、一個 API 業務碼或一個 readback 值作證據**,不得用「看起來正常」這種模糊判定。截圖至多留檔備查,不作為判定依據。

---

## 文件地圖

- `qa-flow.sh` — 流程輔助腳本(bootstrap / scaffold / run / catalog / audit / tools-sync / migrate);把落地動作鎖進腳本,落點鎖 `CLAUDE_PROJECT_DIR`
- `tools/` — 測試資產工具(scaffold 複製進專案 `tests/e2e/tools/`):`qa_config.py`、`baseline.py`、`qa_pytest_plugin.py`、`runs_db.py`、`coverage_md.py`、`gen_catalog.py`、`drift_check.py`、`make_skeleton.py`、`fill_orphans.py`、`coverage_register.py`、`migrate_catalog.py`、`skip_audit.py`、`hardcode_check.py`、`i18n_locator_check.py`、`env_gates.py`、`sweep_residue.py`、`run_by_folder.py`
- `lib/install_tools.py` — 工具複製與版本比對(scaffold / tools-sync 用)
- `templates/qa-webwright.example.json` — 專案參數檔範例(欄位說明見 plugin README「專案參數檔」)
- `templates/conftest_snippet.py` — conftest 掛點片段(sqlite 執行紀錄、A/D skip 閘、drift 摘要、環境閘)
- `methodology/test-plan-design.md` — 覆蓋矩陣、可追溯、必測 checklist、TC 格式、測試資料原則、探索七類、失敗注入、前後端 A/B 對照、範圍展開四格與欄位級驗證
- `methodology/critical-points.md` — TC 預期 → critical point → assert 的對映與證據規範、五條硬規則、斷言隔離度
- `methodology/test-discipline.md` — 核心鐵則(選單導航不直打 URL、mock 在就不准拿外部系統當 skip 藉口、測試庫可破壞)、不打斷、整輪才出報告、直打界線、副作用邊界、判斷與交付的證據要求(掩蓋手段、每批三重重驗、red→green、ablation、掃描器盲區)
- `methodology/test-asset-hygiene.md` — 三層登記與 drift、skip 四分類紀律、xfail 鎖定與反向紀律、故意保留紅燈、缺陷現場當定位錨、直寫 DB 例外判準框架(四條判準、宣稱例外的四步證據、不算例外的理由)、G 類五種 safe 性質與 `G-REVIEWED`
- `knowledge/pitfalls.md` — 踩過的雷與領域知識(A 後端驗證、B 日期時區、C 壞值、D/D2 Windows 啟動與 pytest、E 元件互動、F state 同步、G webwright 操作雷〔僅啟用 webwright 時適用〕、H 外部站 TLS/HTTP2 指紋封鎖、I 長流程 context 經濟、J 定位比對強度與多語系、K 等待時序與 API 攔截、L 斷言盲區、M 種子資料與共用狀態、N 環境多實例與 runner 執行);**持續 append**(新增分類時同步更新此枚舉)
- 沉澱 runner 的官方文件(pytest-playwright / Playwright Test)— 瀏覽器啟動、locator、斷言、fixture
- (選用,僅外部站備用探索)webwright skill 的 `reference/` — 瀏覽器啟動、aria snapshot、log 格式

Files in this skill

  • SKILL.md20.2 KB
  • knowledge/pitfalls.md10.8 KB
  • methodology/critical-points.md5.2 KB
  • methodology/test-plan-design.md13.2 KB
  • qa-flow.sh31.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.