哪些真的需要 UI 測試

  • 流程能從頭到尾跑完。 使用者能從想做的事走到最後的結果。介面底下的任何一層都回答不了這個問題。

  • 跨步驟的狀態。 在某個畫面設定的東西,到下一個畫面仍然生效。真正的缺陷多半集中在這裡。

  • 系統告訴使用者的內容,和實際發生的事一致。 顯示成功訊息卻沒有存下任何紀錄,是應用程式最常說的謊。

哪些不該寫進 UI 測試

驗證規則

  • 透過瀏覽器把每一種錯誤輸入的組合都跑一遍,既慢又脆弱。

  • 在 UI 檢查一種,其餘交給 API。

計算邏輯

  • 單元測試能在幾毫秒內給出答案,失敗訊息也更清楚。

資料準備

  • 為了建立一筆測試資料而點過五個畫面,不但慢,還會因為和你要測的東西無關的原因而壞掉。

測試套件該有多大

兩條實用原則。挑選要涵蓋的流程時,依據它壞掉時有多安靜,而不是它有多重要,因為重要的流程本來就有人盯著,安靜的沒有。另一條是:當維護成本開始吃掉你原本省下的時間,就別再加了——這個轉折點來得比多數團隊預期的還早。

三個習慣

  • 用穩定的定位錨點,不要用 CSS 路徑。 排除大部分因改版而壞掉的情況。

  • 等狀態,不要等時間。 排除大部分的不穩定。

  • 驗證那些重新載入後仍然成立的結果。 去掉成功訊息帶來的虛假信心。

把測試往下挪一層,實際上長什麼樣子

「把檢查挪到介面底下」這個建議很容易認同,卻很難具體執行,所以這裡用一個實際的例子來說明。

假設你有一個瀏覽器測試,會用十四種不同的無效輸入填寫註冊表單,每次都檢查錯誤訊息。它要跑四分鐘,表單版面一改就壞,而且幾乎沒告訴你任何和瀏覽器有關的事。

把它換成一個瀏覽器測試:送出一種無效輸入,確認使用者確實看到錯誤訊息;再加上十三個直接檢查驗證規則的 API 測試。這樣一來,瀏覽器測試回答的是瀏覽器的問題,規則的涵蓋更快也更精準,而且驗證邏輯一有變動,不必再去動任何跟畫面渲染有關的東西。

光靠紀律解決不了的部分

選取器

  • 一次完全不影響功能的改版,就足以讓整套測試變紅。

  • 大部分的維護時間其實都花在這裡。

等待

  • 固定延遲既慢,又還是會不穩定。正確的等待必須知道自己在等什麼。

  • 大部分的不穩定都能追溯到這裡。

人工撰寫的涵蓋範圍

  • 你涵蓋的是有人寫下來的部分,也就是那些有趣的流程,而不是真正會壞掉的流程。

第三項是結構性的問題。當產品的程式碼越來越多由 agent 產出,受限於人工撰寫時間的涵蓋範圍必然會跟不上。以意圖為基礎的測試步驟,加上自動生成的涵蓋範圍,正是為了解決這一塊。

終端機

npm install -g @testsprite/testsprite-cli
testsprite setup

如果不想在本機安裝,儀表板也能做到同樣的事;完整的指令清單則收錄在 CLI 儲存庫。

從儀表板連結儲存庫,測試就會從你原本就會產出的部署開始執行;或者,你也可以改在自己的工作流程中加上一個步驟。

TestSprite 在每一層涵蓋什麼

在同一個專案裡,既涵蓋只有瀏覽器才能回答的瀏覽器流程,也涵蓋底下的 API 層。這正是讓「往下挪一層」的建議變得可行、而不只是理想的原因:驗證規則搬到幾秒內就跑完的 API 測試案例,再用一個瀏覽器案例確認表單確實接上了這些規則。

兩者都是從你的產品生成,再用自然語言微調;瀏覽器測試的步驟描述的是意圖而不是選取器,因此遇到不影響功能的改版,整套測試依然存活得下來。

最後你會得到一套小到讓人願意信任的瀏覽器測試,涵蓋真正重要的使用歷程;而各種規則與邊界情況,則在下一層以更快的速度被涵蓋。

UI 測試要寫多少才剛好?

足以涵蓋那些壞掉會讓你難堪的使用歷程就好,並依據它們壞掉時有多安靜來挑選。其餘的一律往下挪一層。

每個畫面都要測嗎?

不用。測流程,不是測畫面。沒有任何流程經過的畫面,很少值得為它寫一個瀏覽器測試。

那無障礙呢?

機械式的檢查值得自動化,其餘部分仍然需要人工審閱。那是另一個獨立的議題,有自己的工具。

一定要做跨瀏覽器的涵蓋嗎?

取決於你的數據分析。許多團隊會在一個瀏覽器上跑完整的測試套件,其他瀏覽器只跑冒煙測試,這通常是對的取捨。

UI 測試該在什麼時候執行?

每一個 pull request 都跑。頻率再低,失敗時指向的就是一整批變更,而不是單一一筆。

簡短版

在 UI 測流程,其餘的都放到底下去測。

UI 測試應該涵蓋端對端流程、跨步驟的狀態,以及系統告訴使用者的內容是否與實際發生的事一致。驗證、計算與資料準備則屬於下一層,在那裡跑得更快,也更容易定位問題。