使用 Puppeteer 進行 UI 測試真正擅長的事

  • 直接控制瀏覽器。 螢幕截圖、PDF、網路請求攔截、效能追蹤。當你需要瀏覽器做某件特定的事,這是最短的路徑。

  • 資料爬取與自動化。 Puppeteer 有很大一部分的用途根本不是測試,而且它在這方面表現出色。

  • 範圍小、學得完的 API。 你可以把整套 API 裝在腦子裡,而這種情況比它應該有的還要罕見。

瀏覽器測試套件的三項成本

  • 選擇器會壞掉。 一次完全沒動到功能的改版,就能讓整套測試亮紅燈。大部分的維護時間其實都花在這裡。

  • 等待很微妙。 固定延遲既慢又照樣不穩定;正確的等待則要求你知道自己到底在等什麼。多數不穩定的情況都能追溯到這一點。

  • 覆蓋範圍是人寫出來的。 你涵蓋的只是某個人寫下來的部分,也就是當初覺得有趣的流程,而不是真正會出問題的流程。

決定要自動化什麼

直覺會叫你從最重要的功能開始。但更好的篩選標準是:這個東西壞掉時有多安靜。結帳流程壞掉很吵,一小時內你就會聽到消息。匯出、邀請或設定頁面壞掉則很安靜,而安靜的失敗才是最值得優先自動化的。

第二個標準:它多常變動。每個 sprint 都在改的流程,維護成本會高於它帶來的回報。等它穩定下來再涵蓋它。

最能省下時間的三個習慣

  • 使用穩定的屬性。 用專門的測試屬性,而不是 CSS 路徑。光是這一項改變,就能消除大部分因改版而造成的損壞。

  • 等狀態,不要等時間。 等待元素或回應出現,絕對不要等幾毫秒。

  • 驗證那些重新載入後仍能確認的東西。 一則成功的提示訊息,並不能證明任何東西真的被寫進去了。

以意圖為基礎的驗證適合用在哪裡

選擇器損壞與人工撰寫的覆蓋範圍,是結構性的問題,不是靠更好的紀律就能解決。以意圖描述的步驟,能熬過選擇器熬不過的改版;而從你的產品本身生成、而非憑某個人記憶寫出的覆蓋範圍,會包含沒有人會主動寫下的流程。

這不是在反對 Puppeteer,直接控制瀏覽器時它仍然是對的工具。這是在主張:不要用手寫的方式去堆出覆蓋的廣度。

終端機

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

如果你不想安裝任何東西,儀表板也能做到同樣的事。命令列能做的其他所有事情,都記錄在 CLI 儲存庫

讓 Puppeteer 腳本變脆弱的三件事

快速寫出來的腳本,壞掉的原因總是同樣那三個,而每一個都有對應的修正方式——當下做不花什麼成本,拖到後面才做則代價高昂。

第一個是層層串接的 CSS 路徑。一個要往下走四層結構的選擇器,記下的是版面配置而不是元素本身,所以任何人多加一層外層容器都會讓它失效。請錨定在描述「這個元素是什麼」的東西上,而不是「它在哪裡」。

第二個是固定等待。一段長到在慢的時候也夠可靠的延遲,在每個快的時候你都得照付,而遇到最慢的那一次它還是會失敗。請等待元素、回應或狀態變化。

第三個是對你剛剛做過的動作下驗證。按下儲存,然後檢查儲存按鈕還在,什麼也證明不了。驗證的對象必須是只有在操作真的完成後才會成立的東西,這通常意味著把資料重新取回來確認。

每次變更都跑一次

如果建置流程歸另一個團隊管, GitHub App 就是阻力最小的做法:它是一個 webhook,不會改動你儲存庫裡的任何東西,並且會在你的建置回報新版本上線時觸發。如果你希望檢查結果直接顯示在儲存庫裡,用一個 GitHub Actions 步驟也能做到。

TestSprite 在 Puppeteer 旁邊扮演什麼角色

Puppeteer 繼續負責直接控制瀏覽器:螢幕截圖、PDF、網路請求攔截、資料爬取。TestSprite 接手的則是無法隨撰寫人力擴展的那一塊,也就是決定要涵蓋什麼,以及讓它持續能用。

步驟是以意圖而非選擇器的形式儲存,這消除了大部分因改版造成的損壞;等待也由系統處理,不再是你得逐個測試去調的東西。覆蓋範圍是從你的產品生成的,所以那些永遠不會出現在任何人清單上的安靜流程也會被納入。

這在實務上帶來的改變是:亮紅燈的建置當中,真的是 bug 的比例夠高,高到大家願意繼續去看它們——而這正是決定一套瀏覽器測試能不能撐過第二年的關鍵。

有免費的 Puppeteer 書籍 epub 嗎?

這要看出版社,而且會隨時間改變。這個頁面提供的是目前實際在用的知識,而不是某本書的副本。

該用 Puppeteer 還是 Playwright?

Playwright 支援的瀏覽器更廣,內建的等待機制也更好。Puppeteer 比較單純,很適合針對 Chrome 的工作與資料爬取。

我要怎麼減少測試不穩定的情況?

穩定的屬性加上以狀態為基礎的等待,就能消除大部分問題。剩下的通常是環境本身真的不穩定,而那不是任何框架能解決的。

我們應該要有多少個 UI 測試?

比你以為的少,並依「壞掉時有多安靜」來挑選。一套大家信任的小型測試,勝過一套沒人理會的大型測試。

Puppeteer 可以和代理程式驗證並存嗎?

可以,而且這是常見的搭配方式。把 Puppeteer 留給直接控制瀏覽器的工作,廣度則交給自動生成的覆蓋範圍來承擔。

簡短版

API 很簡單,難的是選擇與維護。

使用 Puppeteer 進行 UI 測試,重點大多在於要自動化哪些流程,以及如何讓它們持續能用。使用穩定的屬性、等待狀態、驗證重新載入後仍能確認的東西,並且不要用手寫去堆出覆蓋的廣度。