自動化 UI 測試更好的篩選標準
排序流程時,該看的是「壞掉之後多久才會被發現」,而不是它有多重要。匯出、邀請、設定頁、排程寄出的摘要信。每一項都對某些人很重要,但沒有一項有一群人盯著,所以一個回歸缺陷可以在那裡躺上一個月。
第二個篩選標準:這個流程多常變動。每個 sprint 都在改版的畫面,維護成本會高過它帶來的回報。等它穩定下來再測。
三種成本
選擇器
一次在功能上毫無改變的改版,就足以讓整套測試變紅。
大部分的維護時間其實都花在這裡。
等待
固定延遲既慢又照樣不穩定。正確的等待必須知道自己在等什麼。
大多數的不穩定都可以追回這裡。
手寫出來的覆蓋範圍
你能涵蓋的只有某個人寫下來的部分,也就是那些有趣的流程,而不是真正會壞的流程。
前兩項靠紀律就能處理。第三項則是結構性的:手寫的覆蓋範圍受限於撰寫者的時間,而撰寫者的時間不會變多。
最省事的三個習慣
以穩定的屬性作為定位依據。 用專用的測試屬性,而不是 CSS 路徑。光是這一點,就能消掉大部分因改版而起的失敗。
等狀態,永遠不要等時間。 等元素出現,或等回應回來。固定延遲既慢又不可靠。
驗證重新載入之後仍然成立的結果。 一則成功提示,並不能證明任何東西真的被存下來了。
測試套件為什麼會被刪掉
不是因為它們什麼都測不出來,而是因為「真實失敗」與「維護造成的失敗」的比例糟到讓人乾脆不看結果。當建置變紅的意思從「大概是個 bug」變成「大概又是選擇器」,這套測試就已經失效了,即使它還在跑。
守住這個比例才是真正的工作,而它取決於測試步驟是怎麼被表達的,而不是你有幾個測試。
不依賴撰寫者時間的覆蓋範圍
以意圖表達的步驟撐得過純外觀的改動;而從產品本身生成、而不是從某個人記憶裡生出來的覆蓋範圍,會包含沒有人會想去寫的流程。這正是紀律修不好的那部分成本。
終端機
npm install -g @testsprite/testsprite-cli
testsprite setup
不想在本機安裝的人,用儀表板也能做到同樣的事,而完整的指令則收錄在 CLI 儲存庫。
還能發揮作用的測試套件規模
瀏覽器測試套件存在一個臨界規模,超過之後成本就會高過回報,而這個規模比多數團隊以為的還要小。
限制不在執行時間,而在注意力。三十個流程的測試套件,失敗時會有人去查。三百個流程的測試套件只會產出一份每日清單,而清單只會被分類,不會被閱讀。一旦開始分類,多加的那個測試增加的就是雜訊而不是覆蓋範圍,不管它寫得多好。
所以新增測試時該問的,不是這個流程重不重要,而是:星期五下午看到這個測試失敗,你會不會去查。如果誠實的答案是你只會重跑一次然後繼續做別的事,那這個測試已經是雜訊,寫下來只會讓套件變得更糟。
每次變更都跑一次
觸發的時機比機制更重要。把它掛在你的部署事件上,每一次變更都會被檢查,不需要誰特地做這個決定; GitHub App 可以從儀表板做到這件事,而 GitHub Actions 的步驟則能在你的工作流程內部做到同樣的事。
TestSprite 改變的是這筆帳的哪一部分
第三種成本,也就是受撰寫者時間所限的覆蓋範圍,是紀律修不好的那一種,而 TestSprite 拿掉的正是它。測試案例從你的產品生成,再用白話文調整,所以那些安靜的流程也會被涵蓋,不需要有人騰出一個下午來寫。
前兩種成本則會順帶改善。步驟儲存的是意圖,而不是穿過 DOM 的路徑,所以只是把按鈕挪個位置的改版不會讓整套測試變紅;等待是由系統處理,不必逐個測試去調。這兩項正是大部分維護時間的去處。
這樣守住的,是決定一套測試能不能活下來的那個數字:紅色建置裡真的是 bug 的比例。讓它維持在高點,大家就會繼續看結果,而這正是「真正的覆蓋」與「一個每晚照跑的排程工作」之間的差別。
我們應該要有多少個 UI 測試?
比你以為的還少,而且要依「壞掉之後多久沒人發現」來挑。一套大家信任的小型測試,勝過一套大家無視的大型測試。
合理的通過率該落在哪裡?
只要沒有非常高,大家就會不再看結果。把最後那幾個百分點的不穩定追掉,比新增測試更有價值。
UI 測試應該每次 commit 都跑嗎?
通常的正確答案是每個 pull request 跑一次。每次 commit 都跑往往慢到沒有用,最後就被關掉了。
那視覺回歸測試呢?
那是另一件事,也有它自己的容忍度問題。用在設計系統上很有用,用在應用程式畫面上則雜訊很多。
我們還需要手動測試嗎?
探索性的工作,以及任何需要判斷「這樣感覺對不對」的事情,需要。重複同樣的檢查,則不需要。