在 Android 中使用測試替身

為元素或系統設計測試策略時,有三種 相關的測試方面:

  • 範圍:測試觸控的多少程式碼?測試可以驗證單一 或整個應用程式,或兩者之間。 測試範圍是受測試,通常稱為受試者 測試,也可使用系統下測試測試單元
  • 速度:測試的執行速度有多快?測試速度可能隨毫秒而異 或幾分鐘
  • 擬真度:「實際」程度測試了嗎?舉例來說,如果程式碼的一部分 您只需提出網路要求 測試程式碼是否確實 還是假造結果?如果測試 這表示網路的保真度較高缺點是 測試可能需要更長的時間才能執行,網路故障可能會導致錯誤,或 可能非常昂貴

如要瞭解如何開始定義測試策略,請參閱要測試的項目

隔離與依附元件

當您測試某個元素或元素系統時,則會以隔離的方式執行。適用對象 舉例來說,如果想測試 ViewModel,就不必啟動模擬器並啟動 UI 因為這不會 (或不應) 取決於 Android 架構。

不過,受測試的主體可能「必須」才能運作。適用對象 例如,ViewModel 可能依附於資料存放區才能運作。

當您需要為受測試的主體提供依附元件時,常見的做法 是建立測試替身 (或測試物件)。測試替身 雖然畫面也是在測試中建立的 提供特定行為或資料主要優點在於您可以 既快速又簡單

測試替身

測試替身有多種類型:

假造 有「正常運作」的測試雙重測試實作類別的實作,但實作時適合用於測試,但不適合用於實際工作環境。

範例:記憶體內資料庫。

偽造不需要模擬架構,而且速度較輕。而且建議優先使用

模擬 一個測試雙重,代表您的程式碼設定運作模式,且在互動方面具有期望。如果模擬的互動不符合您定義的要求,就會導致模擬失敗。我們通常會使用模擬架構建立模擬內容,藉此達成上述所有目標。

範例:確認資料庫中的方法僅呼叫一次。

虛設常式 一個測試雙倍的測試可正常運作,但這不會預期您的互動情形。通常以模擬架構建立。為求簡單,偽造比虛設常式更理想。
虛擬 傳遞但未使用的測試替身,例如只需要將其做為參數來提供。

範例:做為點擊回呼的空白函式。

間諜 實體物件的包裝函式,也會追蹤某些額外資訊,類似模擬。通常為了增加複雜度而避免使用。因此,偽造或模擬畫面的偏好更勝過間諜。
陰影 在 Robolectric 中使用虛假。

假使意圖

假設您要對依附介面的 ViewModel 進行單元測試 稱為 UserRepository,並在 UI 上顯示首位使用者的名稱。你可以 實作介面並傳回已知資訊,即可建立假測試替身 資料。

object FakeUserRepository : UserRepository {
    fun getUsers() = listOf(UserAlice, UserBob)
}

val const UserAlice = User("Alice")
val const UserBob = User("Bob")

這個假的 UserRepository 不需要依賴本機和遠端資料 實際工作環境版本會使用的原始碼檔案位於測試來源中 不會與正式版應用程式一起推出。

假依附元件可以傳回已知資料,而不依賴遠端資料來源
圖 1:單元測試中的假依附元件。

以下測試會驗證 ViewModel 是否正確公開第一位使用者 新增至檢視表

@Test
fun viewModelA_loadsUsers_showsFirstUser() {
    // Given a VM using fake data
    val viewModel = ViewModelA(FakeUserRepository) // Kicks off data load on init

    // Verify that the exposed data is correct
    assertEquals(viewModel.firstUserName, UserAlice.name)
}

在單元測試中,用假造取代 UserRepository 很容易,因為 ViewModel 是由測試人員建立。但要更換 因為大型測試中可以任意變更任意元素

取代元件和依附元件插入功能

如果測試無法控制測試中系統的建立作業, 取代測試替身的元件變得更複雜 遵循可測試的設計。

即使是大型端對端測試,使用測試替身也可從中受益,例如 可瀏覽應用程式中完整使用者流程的檢測設備 UI 測試。於 為此,建議您進行密封測試。要避免使用密封的測試 所有外部依附元件,例如從網際網路擷取資料這個 提高可靠性和效能

圖 2:涵蓋大部分應用程式和偽造遠端資料的大型測試。

您可以手動設計應用程式來達到這項彈性,但還是建議您 使用 Hilt依附元件插入架構取代元件 宣傳自家應用程式請參閱 Hilt 測試指南

Robolectric

在 Android 裝置上,您可以使用 Robolectric 架構, 可提供特殊類型的測試替身。Robolectric 可讓你在 或持續整合環境該公式採用 一般 JVM 版本,不需要模擬器或裝置。模擬加載的檢視畫面 資源載入,以及 Android 架構的其他部分 (包含測試替身) 陰影

Robolectric 是模擬器,因此不應取代簡單的單元測試,也不應使用 以便進行相容性測試可加快執行速度並降低成本 但在某些情況下執行 UI 測試是不錯的做法 與 Robolectric 和檢測設備測試相容,並決定何時執行 視需要測試功能或相容性的需求而定。兩個 Espresso 和 Compose 測試可以在 Robolectric 上執行。