iT邦幫忙

2026 iThome 鐵人賽

DAY 13
0
Claude AI

Claude × Playwright:30 天打造你的 Agentic SDET 同事系列 第 13

Day 13|看到異常不代表找到 Bug:教同事先分類

  • 分享至 

  • xImage
  •  

前言

昨天把一輪的結果寫成 results.yaml,六個狀態各司其職,那一包分出 4 個 pass、6 個 fail、1 個 inconclusive、1 個 anomaly。

status 只回答了一半的問題。它說的是「這筆判不判得動」,沒說「這筆帳算誰的」。同樣是 fail,可能是產品寫錯,也可能是測試環境掛了、帳號被別人鎖了,或者根本是我自己操作順序弄反。

今天處理後面那一半。素材是 2026-07-26 到 07-30 十二輪的狀態檔,加上 output/known-false-positives.yaml

為什麼不分類就報,等於開一間誤報工廠

回到昨天那筆「console 有 4 則 error,卻判 pass」。那 4 則逐則對得上:

  • 2 則是載入時 GET /users/me 回的 401
  • 1 則是 POST /users/login 回的 401
  • 1 則是前端攔截後印出來的 Unauthorized 物件

如果每則紅字都當缺陷,那一輪就產出 4 張廢單。而那一輪的檢查點總共才 4 筆。

誤報的代價不是「多一張單」。多一張單只是浪費工程師十分鐘。真正的代價是下一次沒人看你的單 —— 一旦你的單被退過幾次,退你的人就會養成先假設你搞錯的習慣,而那時候你手上真的有一張重要的單也沒用了。

所以今天要立的規矩只有一句:

一個異常有很多種原因,只有一種是產品缺陷。不分類就報,等於開一間誤報工廠。

配一句方法:依證據判類,不靠猜,每一次判類都要指得出依據哪一條 evidence。

實驗:十二輪紀錄裡,category 這個欄位一筆都沒有

這一節是今天最誠實的部分,而且證物是我自己的紀錄。

classify-anomaly 這支 skill 規定判類要寫回 finding,四個欄位:categoryconfidencebasisnext_step。規格寫得清清楚楚。

然後我去查了 output/ 底下所有狀態檔。

十二輪,category 這個欄位一筆都沒有。

實際跑出來的是另一套詞彙。20260730-toolshop-bughunt-gaps/candidates.yaml 裡直接寫:

verdict: BUG
oracle_used: ...
basis: ...
confidence: ...
factors: ...

從 anomaly 一步跳到 BUG,中間那一步整個被跳過了。

後果不是「分類錯」。分類錯至少還留得下一個可以吵的答案;跳過分類的後果是**「為什麼判它是產品的鍋」這句話查不到**。basis 那欄有寫,但寫的是「為什麼它像 bug」,不是「為什麼排除了環境、測資、我自己」。

這正是今天要擋的事,而擋不住的證據就是我自己的十二輪紀錄。跳過分類不會有人來罵你,它只會在第四週變成一堆退不回去的單。

修法也很清楚,而且跟 Day 11、Day 12 是同一條:把 category 變成 results.yaml 的必填欄位,缺了就不准往下。靠形狀強制,不靠記性。

七個類別,只有一類能往下

classify-anomaly 分七類。但這張表真正的欄位不是「它是什麼」,是**「它把責任指向誰」**:

category 責任在 能往下開單嗎
product-bug 產品 可以(續走 test-oracle
environment 服務/基礎設施
test-data 帳號、髒資料、前一步污染
operation-artifact 我自己(順序錯、前置沒做、選錯元素)
flaky 間歇重現 否,記重現率
known-issue 命中已知清單
needs-investigation 證據不夠歸類 否,回去補證據

七類裡只有一類能往下。所以這張表的功能不是分類學,是一道閘:它擋掉的那六類,每一類都是一張本來會被開出去的廢單。

最難分的三類:環境、測資、我自己

口訣先給:服務層壞了是 environment,帳號或資料壞了是 test-data,我自己搞出來的是 operation-artifact。

口訣好記,難的是排除。看兩個實跑的例子。

實例一:423 Locked 為什麼判 test-data

現象是 POST /users/login423,UI 顯示「Account locked, too many failed attempts」。

登入頁顯示帳號已鎖定的錯誤訊息

畫面訊息與 API 狀態碼一致。產品這裡沒做錯任何事,難的是判斷這筆帳算誰的。

要判它是 test-data,得先把另外三類逐一排掉:

  • 排除 environment:服務沒掛。同一輪其他請求都正常,而且 423 是應用層給的正確語意,不是連線失敗。
  • 排除 product-bug:擋得是對的。API 與 UI 一致,鎖定機制本來就該這樣運作 —— 這一筆在 Day 12 的 results.yaml 裡是 pass
  • 排除 operation-artifact:本輪只失敗兩次,而且兩次都被前端攔下、沒有送到 API,不是我們鎖的。

三類都排掉,才輪到 test-data,依據寫「共享 demo 帳號被其他 session 觸發鎖定」。

這裡有一個關鍵值得點出來:能排除 operation-artifact,是因為手上有「我這輪做了什麼」的完整紀錄。沒有 Day 8 到 Day 11 那包證據,這一筆只能寫 needs-investigation。留證跟分類不是兩件事,前者是後者的前提。

實例二:畫面整塊不見了,判 operation-artifact

現象是第一次 snapshot 只讀到「Reltded products」,主商品資訊卡整塊不見。

但同一時間 GET /products/1 回 200,而且全頁截圖證實畫面完整渲染 —— 標題、圖片、價格、規格全都在。

商品頁全頁截圖,主商品資訊卡完整呈現

同一時刻的全頁截圖。snapshot 讀不到的東西,截圖上好好地在那裡。判 operation-artifact 靠的就是這種「另一種觀測方式」的旁證

判 operation-artifact:那是 Angular 渲染與 accessibility tree 快照之間的時間差,是我的觀測時機問題,不是產品的

這一筆在 Day 12 的狀態是 inconclusive,今天給它 category。兩層詞彙各司其職status 說「判不判得動」,category 說「這筆帳算誰的」。同一筆東西可以是「判不動」而且「算我自己頭上」。

這三類的判準都不在畫面上

旁證:服務狀態、我的操作紀錄、另一種觀測方式的結果。只盯著畫面看,這三類永遠分不開。

要誠實講一件事:這十二輪裡沒有一筆真的判成 environment。 全部都在 demo 站上跑,服務一次都沒掛過。所以上面那個口訣裡,environment 是唯一沒有實例的一類,它的判準目前只是紙上談兵。

同一個畫面現象,兩種結論

購物車數量填 -5,畫面 Total 顯示 -$70.75

這一筆算誰的?光看畫面答不出來,要看你多做的那一步:

多做的那一步 結論
reload 後回復成 1、變更沒觸發寫入呼叫 前端零驗證,後端從未收到,問題在前端
reload 後負數還在、確實寫進後端 後端也沒驗證,嚴重度完全不同

實測是前者。判類依據寫成一句:「變更未觸發寫入呼叫、reload 後回復 1(從未寫入後端)→ 問題在前端,排除環境。」

這一節要立的規矩是:basis 不是把現象再說一次,是寫你排除了什麼、憑哪條證據排除。

「畫面顯示負數」不是 basis,那是現象。「reload 後回復成 1」才是 basis,因為它排掉了一整條分支。

跨 finding 檢查:同一個簽章歸一類

分類不是逐筆做完就算。收工前還要橫著看一遍。

規則是:多筆共用同一個錯誤簽章(同一個逾時、同一個 5xx、同一個連線錯),很可能是 environment 或整層事件,歸一類,不要逐筆當產品缺陷。

素材就是第一節那 4 則 401:其中三則指向同一件事(未登入所以沒有 session),第四則是前端把它印出來。一件事,不是四件。

反過來也要警告:不能把不同簽章硬併成一類,那會漏掉真的缺陷。判準是簽章,不是「看起來很像」。

這一條目前也還沒真的執行過。上面那 4 則 401 是我事後查檔案對出來的,不是當時跑的動作。

已知問題清單:分類唯一會累積下來的東西

這一節最容易被略過,但實務上最有用。

output/known-false-positives.yaml 現在兩筆,都在 2026-07-27 拍板:

pattern scope 判成
GET /users/me 回 401,且發生在未登入頁面 anonymous-only 非缺陷(前端把它記成 error)
POST /users/login 回 423(共享測試帳號) test-account only test-data,已驗證為暫時性鎖定

每筆四個欄位:patternscopereasondecided_by 加日期。

decided_by 是重點。 門檻寫得很硬:進這份清單等於已經有人拍板。還沒人決定的(needs-spec)不准放進來,否則這份清單會變成「我覺得應該不是問題」的垃圾桶。

為什麼值得專講?因為這是唯一會讓下一輪自動閉嘴的東西。其他分類結果都只影響當下那一輪,只有這份清單跨輪生效。

scope 那一欄不要省。同一個 401 在未登入頁是預期,在已登入頁就是缺陷。沒有 scope 的清單會把真缺陷一起消音。

這一類同樣還沒有實跑示範:清單有兩筆,但還沒有留下「下一輪撞到它、自動閉嘴」的紀錄。

小結

一個異常先問它算誰的帳,七類裡只有 product-bug 能往下;最難分的環境、測資、我自己三類,判準都不在畫面上而在旁證,所以 basis 要寫「我排除了什麼、憑哪條證據」,不是把現象再講一次。逐筆判完還要橫著看一次,同簽章的歸成一件。判完寫回該筆 finding 四個欄位:categoryconfidencebasisnext_stepflaky 必記重現率,needs-investigation 必寫還缺什麼證據,不准只寫「待查」就放著。

                        一個異常
                            │
                            ▼
                  這筆帳算誰的?(看旁證)
                            │
    ┌──────────┬──────────┬─┴────────┬──────────┬──────────┐
    ▼          ▼          ▼          ▼          ▼          ▼
 environment test-data operation  flaky   known-issue needs-
 服務掛了    帳號/髒資料 artifact  間歇重現  命中清單   investigation
             被別人鎖    我自己弄的            自動閉嘴   證據不夠
    │          │          │          │          │          │
    └──────────┴──────────┴────┬─────┴──────────┴──────────┘
                               │
                     這六類都不能開單
                               │
                               ▼
                         product-bug
                          (只有這一類)
                               │
                               ▼
              收工前橫著看一次:同簽章歸一件
                               │
                               ▼
              寫回 finding:category/confidence
                          basis/next_step
              basis = 我排除了什麼,憑哪條證據
                               │
                               ▼
                    往下交給 test-oracle

誤報的代價不是多一張單,是下一次沒人看你的單,四則 401 全開成缺陷,那一輪就是四張廢單配四個檢查點。basis 寫的是排除不是現象,「畫面顯示負數」不算依據,「reload 後回復成 1」才算。而規格寫了不等於做得到:十二輪紀錄裡 category 一筆都沒有,靠記性守不住的規矩要靠形狀守,把它變成必填欄位,缺了就不准往下。

下一步

分類完,手上剩下的 product-bug 才有資格往下。

但「往下」不是直接開單。下一關是:你能不能把它寫成一份別人照著就能重現的報告 —— 而且那個別人拿不到你的推理,跟 Day 11 的交棒標準是同一條。

明天寫第一份 Bug Report。


參考資料

  1. Claude Code Docs — Extend Claude with skills - 怎麼把七選一變成每次都填的形狀
  2. MDN — 423 Locked - 實例一那個狀態碼的語意
  3. MDN — 401 Unauthorized - 第一節那 4 則 error 的來源
  4. Playwright — Trace Viewer - 排除 operation-artifact 要靠的操作紀錄
  5. Michael Bolton — DevelopSense - 誤報在測試回報裡的成本,這一天第一節那個論點的來源
  6. Toolshop(Practice Software Testing) - 受測站與對照組
  7. 本專案 skills/observe/classify-anomaly/ - 七類與四個欄位的真檔
  8. 本專案 output/known-false-positives.yaml - 第六節那兩筆

上一篇
Day 12|Pass 和 Fail 之外的多重宇宙:設計結構化測試結果
下一篇
Day 14|第一次寫 Bug Report:從發現到可重現報告
系列文
Claude × Playwright:30 天打造你的 Agentic SDET 同事16
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言