Install
npx skillscat add arthurc02/skillhub/flaky-test Install via the SkillsCat registry.
SKILL.md
偶發紅:找機制,不找運氣
偶發紅是確定性的 bug,只是觸發條件你還沒控制住。 重跑變綠只證明那次沒撞到條件。
不准的修法
- 加重試、把逾時拉長、加
sleep——它們只降低撞到的機率,條件還在。 - 標成 skip、quarantine 或「已知不穩」而沒有排定修正。
- 把斷言放寬到兩種結果都接受。
程序
- 蒐集紅的那一次的完整輸出:失敗訊息、執行順序、同時在跑的其他測試、時間戳。CI 紅就去拿那個 job 的 log,不要只看摘要。
- 列出它依賴、但沒有自己控制的東西,逐項問「別人能不能在我讀之前改它」:
- 共享的資料列、檔案、連線池、port、全域變數、單例、快取;
- 前一條測試留下、還沒清完的東西(背景清理、非同步刪除、還在跑的 goroutine 或 timer);
- 時鐘、亂數、排序不穩的查詢(沒有
ORDER BY、map 迭代); - 等待條件:用 sleep 等、或探針查「任何一個」等待者而不是自己那一個;
- 前一條測試逾時後沒有收掉的殘留,卡住後面所有測試。
- 刻意重現:讓那個條件必定成立——拉長清理、換執行順序、
-count=N/--repeat、平行度開大、只跑相鄰的兩條。重現不出來就還沒找到機制,不要動手修。 - 修根因:等確定性的訊號(等自己那一筆清理完成、等那個事件),隔離共享狀態,或讓查詢順序確定。
- 證明:同一個重現,修正前紅、修正後綠。單改一行常常紅不出來,所以證據是那個重現,不是突變。最後移除重現用的鷹架,確認 diff 只剩修正。
- 找同類:同一個機制通常不只一處,搜一遍用同一個 helper 或同一種等法的測試。
回報
<測試> — 機制:<誰在什麼時候改了它依賴的什麼> — 重現:<怎麼讓它必紅>(修正前 FAIL)— 修法:<改成等什麼/隔離什麼> — 修正後同一重現 PASS — 同類:<搜了什麼、找到幾處>
沒有那個重現,就不要寫「修好了偶發紅」。