QA 自動化不是寫更多測試,是建閉環
很多團隊衡量自動化成熟度的方式是「我們寫了幾個測試」。這個數字幾乎沒有意義。
真正決定價值的是跑完之後發生什麼:測試結果透明嗎?失敗會不會自己重跑?季末講得出成效數字嗎?票務進來會不會自動變成測試?如果這些都是「人工」或「不知道」,那你寫再多測試,都只是一堆黑箱。
自動化的天花板不在「寫得多」,在「有沒有形成閉環」。這篇是一條跑真交易所(帳戶/出入金/訂單簿/餘額,錯了會出事)的完整閉環怎麼組起來的。
全景:一條四層閉環
flowchart LR
T[票務系統<br>AC + MR] --> E[AI 引擎層<br>codegen]
E --> B[BDD 場景庫<br>單一真相源<br>12,293 場景]
B --> R[Robot 執行層<br>1,620 測試]
R --> J[CI 平行跑<br>只重跑失敗]
J --> S[(結果 Sheet)]
S --> D[儀表板<br>自動化指標]
D -.閘門觸發.-> J
style E fill:#f59e0b,color:#fff
style B fill:#06b6d4,color:#fff
style R fill:#10b981,color:#fff
style D fill:#7c3aed,color:#fff
四層各司其職:AI 引擎產碼、BDD 場景庫是唯一真相源、Robot 執行層跑真環境、儀表板收指標並反過來觸發重跑。重點不是任何單層多聰明,是四層串成一條會自己轉的環。
一、單一真相源:WHAT vs HOW 分離
閉環的地基,是把測試案例從無版控的 Excel(動輒幾 MB、沒人敢動)搬進 git。搬進來之後做一件關鍵的事——WHAT 跟 HOW 分兩層:
flowchart TB
subgraph WHAT[場景庫 · 測什麼]
W1["Given/When/Then<br>測試意圖 + 預期"]
W2["user level 矩陣"]
end
subgraph HOW[Robot · 怎麼測]
H1["自動化實作碼"]
end
WHAT -->|只靠案例名字對映| HOW
style WHAT fill:#06b6d4,color:#fff
style HOW fill:#10b981,color:#fff
- 場景庫存「測什麼」:意圖、預期、user level 矩陣,用業務語言寫成 Given/When/Then。QA/PM 看得懂、能 review。
- Robot 層存「怎麼測」:自動化程式碼。
- 兩層只靠測試案例的名字對映,各自獨立演進。
這樣 QA/PM 不用讀一行自動化 code 就能 review 測試意圖,而自動化實作可以重構、可以換 driver,完全不動到 spec。這 12,293 個場景(App + Web 合計、近百個模組)就是這樣變成可 diff、可 MR review、可 branch-per-ticket 的。
level 參數化是另一個放大器:一個「人類場景」用 level 矩陣展開成 N 個 Robot 測試(例如同一個提領流程,對 L0/L1/L2/未綁銀行各有不同預期)。這就是為什麼「12k 場景」對映到的自動化面比 12k 大得多。
二、票務驅動:票進來,自動變成測試骨架
閉環的入口是票務。一張功能票有驗收條件(AC)和對應的 MR,這些就是產測試的原料:
票(AC + MR) → AI 產 Python 測試骨架 + harness → 寫進測試分支 → merge
單元測試要行級細節、整合測試只要邊界,所以餵 context 時主票給完整 diff、聚合子票只給檔名(省約 95% token)。產出的不是「能跑就好」的碼,而是符合團隊慣例的碼——因為慣例本身被寫成了機器可檢查的規範(見下一節)。
三、data-driven 預期:別把「會過期的真相」寫死
跑真交易所最容易犯的錯,是把費率、提領上下限、上架幣種寫死在測試裡。這些東西天天在變,寫死的測試明天就是紅的(而且是假紅)。
正解:對平台自己的真相源驗證。每次跑之前先抓一份即時的交易所 metadata 快照(幣別確認數、提領上下限、維護狀態、下市對、VIP 費率……),在 runtime 導出預期值。
測試斷言的不是「手續費應該是 0.1%」,而是「手續費應該等於平台此刻宣告的值」。真相源變了,測試自動跟上,不用改一行 code。
四、把 flaky 夜跑變確定性:三訊號就緒閘門
夜跑 App 測試最惱人的是 flaky——早上來看一片紅,重跑又全綠。多數 flaky 的根因是「還沒真的 ready 就開始測」。
以 Android 冷開機為例,別用盲目的 sleep 30,改用三訊號就緒閘門:
flowchart LR
C[冷開 emulator] --> S1{sys.boot_completed?}
S1 -->|是| S2{settings service<br>有回應?}
S2 -->|是| S3{IME 輸入法<br>綁定完成?}
S3 -->|是| GO[開始測試 ✅]
S1 -->|否| S1
S2 -->|否| S2
S3 -->|否| S3
style GO fill:#10b981,color:#fff
三個訊號都過才開跑。搭配:殺乾淨舊的 emulator / session(別讓上一輪殘留污染)、調冷開參數(不載入 snapshot、指定 GPU 模式、加大 partition 防 APK 累積爆磁碟)。這樣就能把「flaky 夜跑」變成「確定性夜跑」。
五、閉環收尾:只重跑失敗 + 自動回流
最後一段,也是「閉環」真正閉起來的地方:
flowchart LR
F[完整跑一輪] --> S[(寫結果 Sheet)]
S --> G{通過率 > 85%?}
G -->|是, 進閘門| RR[CI 只重跑<br>失敗的]
RR --> M[rebot 合併結果]
M --> S2[(回填 Sheet)]
S2 --> D[儀表板消費]
D --> N[Slack 通知]
style G fill:#f59e0b,color:#fff
style RR fill:#10b981,color:#fff
style D fill:#7c3aed,color:#fff
- 完整跑一輪,結果寫進 Sheet。
- 儀表板讀失敗標記,過通過率閘門(例如 >85%)才觸發重跑——用
<tag>對 Sheet,不是用 test name(名字會改、tag 穩定)。 - CI 只重跑失敗的、再用
rebot合併,不重跑全套。 - 結果回填 Sheet → 儀表板消費 → Slack 通知。
按 user level 分組平行跑、只重跑失敗、合併——這幾步讓「一個 flaky 失敗」不用賠掉整輪的時間。
別忘了:慣例即程式碼 + 誠實計量
慣例即程式碼:AI codegen 需要一個「機器可檢查的目標契約」。把團隊慣例(keyword 命名、xpath 大小寫、「≥2 個斷言要用 continue-on-failure」等)寫成幾百行規範,再配一個 linter skill 對分支 diff 報 🔴🟡🟢——這就是 AI 產碼的驗收閘門。沒有這層,AI 產的碼會慢慢腐化成各寫各的。
誠實計量(管理層最在意的一條):
- 自動化數量兩來源對帳——從執行結果 Sheet 讀,再用季末 commit 快照數(數 Robot 的
*** Test Cases ***、JS 的test())交叉驗,對得上才報。 - AI 測試輔助 = 按規格手刻加速 + 人把關,絕不寫成「全自動、不耗人力」。取材分界也要明確:哪些算「QA 用 AI」、哪些屬另一個專案,不能混報。
浮誇一次,就賠掉整個儀表板的公信力。閉環的最後一塊,是讓數字誠實到主管敢拿去對 keynote。
一句話
自動化的價值不在「寫了幾個測試」,在「跑完之後這條路會不會自己轉」——從票務進來、產碼、跑真環境、只重跑失敗、回流儀表板。你建的不是測試,是一條會自我修復的閉環。