螢幕截圖測試

螢幕截圖測試是驗證應用程式 UI 的有效方法。螢幕截圖測試可用於元件、功能和應用程式測試。

您可以使用第三方工具建立檢測和本機螢幕截圖測試。如果您使用 Compose,可以使用官方的 Compose 預覽螢幕截圖測試工具

定義

螢幕截圖測試會擷取 UI 的螢幕截圖,並與先前核准的圖片 (稱為「參考」或「黃金」) 進行比較:

螢幕截圖測試會比較兩張圖片,一張是新的螢幕截圖,另一張是參考圖片。
圖 1. 螢幕截圖測試會比較兩張圖片

如果圖像相同,測試通過。如果兩者之間有差異,工具就會建立報表:

螢幕截圖測試報告,兩側顯示參考螢幕截圖和新螢幕截圖,中間則顯示兩者之間的差異。
圖 2. 螢幕截圖測試報告,兩側分別顯示參考螢幕截圖和新螢幕截圖,中間則顯示兩者之間的差異。

收到這份報告後,您可以採取兩種回應方式:

  • 發現新程式碼有錯誤,並加以修正。
  • 核准新的螢幕截圖,並使用新圖片取代參考圖片。

螢幕截圖測試與一般測試的工作流程不同,因為失敗的測試不一定代表發生錯誤。

優點

螢幕截圖測試的優點如下:

  • 螢幕截圖測試會在每次測試中執行多項斷言。舉例來說,單一測試可以檢查顏色、邊界、大小和字型。
  • 與同等行為測試相比,螢幕截圖測試更容易編寫、瞭解和維護。
  • 特別適合用來驗證及擷取不同螢幕大小的迴歸。

缺點

不過,螢幕截圖測試也有缺點:

  • 處理參考圖片可能會很麻煩,因為大型專案可能會產生數千個 PNG。
  • 不同的平台 (Linux、Max 和 Windows) 會產生略有不同的螢幕截圖。
  • 比起同等行為測試,這些測試的速度較慢。
  • 大量的螢幕截圖測試可能會導致問題,例如單一變更會影響數千張螢幕截圖。

下列各節將提供解決這些問題的最佳化建議。

盡量減少螢幕截圖測試

您應盡量減少螢幕截圖測試次數,同時盡可能提高回饋和回歸涵蓋率。

不同 UI 狀態的組合可能會讓測試次數快速增加。您可以透過下列方式驗證應用程式使用者介面的部分內容:

  • 針對不同主題
  • 使用不同的字型大小
  • 在不同螢幕大小或邊界內部

如果您為應用程式的每個元件、版面配置和畫面進行這項操作,您就會得到數千個螢幕截圖檔案,而這些檔案大多都未提供任何意見回饋。

舉例來說,如果您想測試採用淺色和深色主題的自訂按鈕,以及 3 種字型大小,不必建立所有按鈕的組合。您可以改為只選擇其中一個主題。這是因為按鈕對長字詞的反應方式不會影響主題。

您可以省略部分 UI 屬性組合。
圖 3. 您可以省略某些 UI 屬性組合。

儲存參考圖片

參考 (或黃金) 圖片通常是 PNG 檔案,可檢查至您的來源控管。不過,Git 和大部分的原始碼控管管理工具最適合用於文字檔案,而非大型二進位檔案。

您可以透過下列 3 種方式管理這些檔案:

  • 繼續使用 Git,但試著盡量減少儲存空間用量。
  • 使用 Git LFS
  • 使用雲端服務管理螢幕截圖。

平台差異

螢幕截圖測試會使用低階平台 API 繪製文字或陰影等特定功能,而平台可以以不同方式實作這些功能。如果您在 Mac 上進行開發,並在本機儲存新的螢幕截圖,可能會在 Linux CI 電腦上看到失敗的測試。

有 2 種方法可以解決這個問題:

  • 容許小幅變更
  • 在伺服器上擷取螢幕截圖

容許小幅變更

您可以設定大多數螢幕截圖測試程式庫,讓系統在比較兩張螢幕截圖時,允許出現些微差異。

方法有以下兩種:

  • 根據修改過的像素百分比或像素值總差異百分比設定容差。
  • 以巧妙的區別 (用來比較螢幕截圖的演算法) 來驗證結構和語意相似度,而非像素。

這種方法的缺點是可能會產生偽陽性,且無法偵測低於閾值的錯誤,或誤認為相似的錯誤。

在伺服器上擷取螢幕截圖

如要使用像素完美的螢幕截圖比對工具,您必須確保測試在相同條件下擷取螢幕截圖。如要這麼做,您可以使用持續整合 (CI) 系統或採用雲端服務。

舉例來說,您可以在 CI 工作流程中建立步驟,執行下列操作:

  1. 執行螢幕截圖測試 (僅限於未使用完美像素比對時)。
  2. 如果上一個步驟失敗,系統會記錄新的螢幕截圖。
  3. 將新檔案提交至分支。
替代文字:圖表顯示如何在 CI 上擷取螢幕截圖
圖 4. 圖表:顯示如何在 CI 上擷取螢幕截圖

使用這個方法時,螢幕截圖測試在 CI 上絕對不會失敗,但會為您修改變更。這樣一來,您和變更審查人員就能透過合併變更來接受新的螢幕截圖。

螢幕截圖測試工具

為進行螢幕截圖測試時,請考量可用工具和程式庫之間的主要差異:

  • 環境:在主機上執行的本機測試,或在模擬器或裝置上執行的檢測設備測試。
  • 算繪引擎:主機端螢幕截圖解決方案可使用 Layoutlib (Android Studio 用於預覽的算繪引擎) 或 Robolectric 原生圖形 (RNG)。
    • 以 Layoutlib 為基礎的架構著重於轉譯靜態元件,使用不同的狀態顯示不同的行為。通常更容易使用。
    • 整合 RNG 的架構可以使用 Robolectric 的所有功能,讓測試範圍更廣。