測試 Android 應用程式的基礎知識

本頁將說明 Android 應用程式測試的核心原則,包括主要最佳做法及其優點。

測試的好處

測試是應用程式開發流程中不可或缺的一環。藉由持續測試應用程式,您可以在公開發布應用程式前,驗證應用程式的正確性、功能行為和可用性。

您可以手動測試應用程式,方法是瀏覽應用程式。您可能會使用不同的裝置和模擬器、變更系統語言,並嘗試產生每個使用者錯誤或遍歷每個使用者流程。

不過,手動測試的擴充性不佳,而且很容易忽略應用程式行為的迴歸。自動測試是指使用工具為您執行測試,這種方式速度較快、可重複執行,而且通常能在開發程序早期提供更多實用意見回饋。

Android 中的測試類型

行動應用程式相當複雜,必須在許多環境中正常運作。因此,測試類型也相當多元。

主旨

舉例來說,根據主體,測試類型會有所不同:

  • 功能測試:應用程式是否能正常運作?
  • 效能測試:是否能快速有效率地完成工作?
  • 無障礙測試:是否能順利搭配無障礙服務運作?
  • 相容性測試:是否能在所有裝置和 API 級別上正常運作?

範圍

測試也會因大小隔離程度而異:

  • 單元測試小型測試只會驗證應用程式的一小部分,例如方法或類別。
  • 端對端測試或大型測試可同時驗證應用程式的較大區塊,例如整個畫面或使用者流程。
  • 中型測試介於兩者之間,可檢查兩個或多個單元之間的整合
測試可分為小型、中型或大型。
圖 1:一般應用程式中的測試範圍。

測試的分類方式有很多種,不過,對應用程式開發人員而言,最重要的差異在於測試的執行位置。

檢測設備測試與本機測試

您可以在 Android 裝置或其他電腦上執行測試:

  • 檢測設備測試會在 Android 裝置上執行,無論是實體裝置或模擬裝置皆可。應用程式會與測試應用程式一併建構及安裝,測試應用程式會插入指令並讀取狀態。設備測試通常是 UI 測試,會啟動應用程式,然後與其互動。
  • 本機測試會在開發機器或伺服器上執行,因此也稱為「主機端測試」。通常很小且速度很快,可將受測主體與應用程式的其餘部分隔離。
測試可以在裝置上以設備測試的形式執行,也可以在開發電腦上以本機測試的形式執行。
圖 2:依執行位置劃分的測試類型。

並非所有單元測試都是在本機執行,也並非所有端對端測試都是在裝置上執行。例如:

  • 大型本機測試:您可以使用在本機執行的 Android 模擬器,例如 Robolectric
  • 小型檢測設備測試:您可以驗證程式碼是否能與架構功能 (例如 SQLite 資料庫) 搭配運作。您可以在多部裝置上執行這項測試,檢查與多個 SQLite 版本的整合情形。

範例

下列程式碼片段示範如何在檢測設備 UI 測試中與 UI 互動,點選某個元素並驗證是否顯示另一個元素。

Espresso

// When the Continue button is clicked
onView(withText("Continue"))
    .perform(click())

// Then the Welcome screen is displayed
onView(withText("Welcome"))
    .check(matches(isDisplayed()))

Compose UI

// When the Continue button is clicked
composeTestRule.onNodeWithText("Continue").performClick()

// Then the Welcome screen is displayed
composeTestRule.onNodeWithText("Welcome").assertIsDisplayed()

下列程式碼片段顯示 ViewModel 的部分單元測試 (本機、主機端測試):

// Given an instance of MyViewModel
val viewModel = MyViewModel(myFakeDataRepository)

// When data is loaded
viewModel.loadData()

// Then it should be exposing data
assertTrue(viewModel.data != null)

可測試的架構

採用可測試的應用程式架構後,程式碼會遵循特定結構,方便您輕鬆測試不同部分。可測試的架構還有其他優點,例如可讀性、可維護性、可擴充性和可重複使用性更高。

無法測試的架構會產生下列項目:

  • 測試規模更大、速度更慢、更不穩定。無法進行單元測試的類別可能必須透過較大規模的整合測試或 UI 測試涵蓋。
  • 測試不同情境的機會較少。測試範圍越大,速度就越慢,因此測試應用程式的所有可能狀態可能不切實際。

如要進一步瞭解架構指南,請參閱「應用程式架構指南」。

解耦方法

如果可以從其餘部分擷取函式、類別或模組的一部分,測試就會更輕鬆有效。這種做法稱為「解除耦合」,是可測試架構最重要的概念。

常見的解耦技術包括:

  • 將應用程式分成「簡報」、「網域」和「資料」等。您也可以將應用程式拆分成多個模組,每個模組對應一項功能。
  • 避免在具有大型依附元件的實體 (例如活動和片段) 中新增邏輯。將這些類別做為架構的進入點,並將 UI 和商業邏輯移至其他位置,例如可組合函式、ViewModel 或網域層。
  • 避免在包含商業邏輯的類別中直接架構依附元件。 舉例來說,請勿在 ViewModel 中使用 Android Context
  • 輕鬆替換依附元件。舉例來說,請使用介面,而非具體實作。即使不使用 DI 架構,也請使用依附元件插入

後續步驟

現在您已瞭解測試的重要性,以及兩種主要測試類型,接下來可以閱讀「測試項目」一文,或瞭解測試策略

或者,如果您想建立第一個測試並從實作中學習,請參閱測試程式碼研究室