ArthurC02

flaky-test

測試偶發紅、單獨跑綠但整套跑紅、或 CI 紅而本機重跑就綠時使用。找出讓它紅的機制、刻意重現、修根因、證明修正前紅修正後綠——不加重試、不拉長逾時、不標成 skip。

ArthurC02 1 Actualitzat fa 2 setm.
GitHub

Instal·la

npx skillscat add arthurc02/skillhub/flaky-test

Instal·la des del registre de SkillsCat.

SKILL.md

偶發紅:找機制,不找運氣

偶發紅是確定性的 bug,只是觸發條件你還沒控制住。 重跑變綠只證明那次沒撞到條件。

不准的修法

  • 加重試、把逾時拉長、加 sleep——它們只降低撞到的機率,條件還在。
  • 標成 skip、quarantine 或「已知不穩」而沒有排定修正。
  • 把斷言放寬到兩種結果都接受。

程序

  1. 蒐集紅的那一次的完整輸出:失敗訊息、執行順序、同時在跑的其他測試、時間戳。CI 紅就去拿那個 job 的 log,不要只看摘要。
  2. 列出它依賴、但沒有自己控制的東西,逐項問「別人能不能在我讀之前改它」:
    • 共享的資料列、檔案、連線池、port、全域變數、單例、快取;
    • 前一條測試留下、還沒清完的東西(背景清理、非同步刪除、還在跑的 goroutine 或 timer);
    • 時鐘、亂數、排序不穩的查詢(沒有 ORDER BY、map 迭代);
    • 等待條件:用 sleep 等、或探針查「任何一個」等待者而不是自己那一個;
    • 前一條測試逾時後沒有收掉的殘留,卡住後面所有測試。
  3. 刻意重現:讓那個條件必定成立——拉長清理、換執行順序、-count=N/--repeat、平行度開大、只跑相鄰的兩條。重現不出來就還沒找到機制,不要動手修。
  4. 修根因:等確定性的訊號(等自己那一筆清理完成、等那個事件),隔離共享狀態,或讓查詢順序確定。
  5. 證明:同一個重現,修正前紅、修正後綠。單改一行常常紅不出來,所以證據是那個重現,不是突變。最後移除重現用的鷹架,確認 diff 只剩修正。
  6. 找同類:同一個機制通常不只一處,搜一遍用同一個 helper 或同一種等法的測試。

回報

<測試> — 機制:<誰在什麼時候改了它依賴的什麼> — 重現:<怎麼讓它必紅>(修正前 FAIL)— 修法:<改成等什麼/隔離什麼> — 修正後同一重現 PASS — 同類:<搜了什麼、找到幾處>

沒有那個重現,就不要寫「修好了偶發紅」。

Categories