常見模式

您可以使用成熟的方法和模式測試 Compose 應用程式。

獨立測試

ComposeTestRule 可讓您啟動顯示任何可組合項的活動:完整應用程式、單一畫面或小型元素。此外,也建議您檢查可組合項是否已正確封裝,且可以獨立運作,以便進行更輕鬆、更聚焦的 UI 測試。

這不代表只能建立單元 UI 測試。對 UI 中範圍較大的部分進行的測試也同樣重要。

設定自己的內容後存取活動和資源

您通常需要使用 composeTestRule.setContent 設定要測試的內容,也需要存取活動資源,例如聲明顯示的文字與字串資源相符。不過,如果活動已經呼叫 createAndroidComposeRule(),您無法再為使用 createAndroidComposeRule() 建立的規則呼叫 setContent

為此,常見的模式是使用空白活動 (例如 ComponentActivity) 建立 AndroidComposeTestRule

class MyComposeTest {

    @get:Rule
    val composeTestRule = createAndroidComposeRule<ComponentActivity>()

    @Test
    fun myTest() {
        // Start the app
        composeTestRule.setContent {
            MyAppTheme {
                MainScreen(uiState = exampleUiState, /*...*/)
            }
        }
        val continueLabel = composeTestRule.activity.getString(R.string.next)
        composeTestRule.onNodeWithText(continueLabel).performClick()
    }
}

請注意,您必須在應用程式的 AndroidManifest.xml 檔案中新增 ComponentActivity。方法很簡單,只要將這個依附元件新增至模組即可:

debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")

自訂語意屬性

您可以建立自訂語意屬性,向測試公開資訊。如要執行這項操作,請定義新的 SemanticsPropertyKey,並透過 SemanticsPropertyReceiver 提供。

// Creates a semantics property of type Long.
val PickedDateKey = SemanticsPropertyKey<Long>("PickedDate")
var SemanticsPropertyReceiver.pickedDate by PickedDateKey

現在在 semantics 修飾符中使用該屬性:

val datePickerValue by remember { mutableStateOf(0L) }
MyCustomDatePicker(
    modifier = Modifier.semantics { pickedDate = datePickerValue }
)

在測試中,使用 SemanticsMatcher.expectValue 斷言屬性的值:

composeTestRule
    .onNode(SemanticsMatcher.expectValue(PickedDateKey, 1445378400)) // 2015-10-21
    .assertExists()

驗證狀態還原

重新建立活動或程序後,請確認 Compose 元素的狀態是否已順利還原。您可以直接使用 StateRestorationTester 類別執行這類檢查,而不必依賴重新建立活動。

這個類別可讓您模擬可組合項的重新建立。請務必驗證 rememberSaveable 的實作方式。


class MyStateRestorationTests {

    @get:Rule
    val composeTestRule = createComposeRule()

    @Test
    fun onRecreation_stateIsRestored() {
        val restorationTester = StateRestorationTester(composeTestRule)

        restorationTester.setContent { MainScreen() }

        // TODO: Run actions that modify the state

        // Trigger a recreation
        restorationTester.emulateSavedInstanceStateRestore()

        // TODO: Verify that state has been correctly restored.
    }
}

測試不同的裝置設定

Android 應用程式需要適應許多變化條件,例如視窗大小、語言代碼、字型大小、深色和淺色主題等等。這些條件的大部分內容皆源自使用者控制的裝置層級值,並透過目前的 Configuration 例項公開。由於測試必須設定裝置層級的屬性,因此直接在測試中測試不同的設定很困難。

DeviceConfigurationOverride 是專供測試的 API,可讓您以本機方式模擬測試中的 @Composable 內容,以便模擬不同的裝置設定。

DeviceConfigurationOverride 的隨附物件具有下列擴充功能函式,可覆寫裝置層級設定屬性:

如要套用特定覆寫值,請在對 DeviceConfigurationOverride() 頂層函式發出呼叫時,將測試中的內容包裝起來,並將覆寫值做為參數傳遞。

舉例來說,以下程式碼會套用 DeviceConfigurationOverride.ForcedSize() 覆寫值,在本機變更密度,強制將 MyScreen 可組合項轉譯為大型橫向視窗,即使執行測試的裝置不直接支援該視窗大小也一樣:

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.ForcedSize(DpSize(1280.dp, 800.dp))
    ) {
        MyScreen() // Will be rendered in the space for 1280dp by 800dp without clipping.
    }
}

如要一併套用多個覆寫值,請使用 DeviceConfigurationOverride.then()

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.FontScale(1.5f) then
            DeviceConfigurationOverride.FontWeightAdjustment(200)
    ) {
        Text(text = "text with increased scale and weight")
    }
}

其他資源

  • 在 Android 上測試應用程式:主要的 Android 測試專頁可讓您更深入瞭解測試基礎知識和技巧。
  • 測試基礎知識進一步瞭解測試 Android 應用程式的核心概念。
  • 本機測試您可以在本機上執行部分測試。
  • 檢測設備測試建議您也執行檢測設備測試。也就是直接在裝置上執行的測試。
  • 持續整合持續整合可讓您將測試整合至部署管道。
  • 測試不同螢幕大小由於使用者可使用的裝置種類繁多,因此您應測試各種螢幕大小。
  • Espresso:雖然適用於以 View 為基礎的 UI,但 Espresso 知識仍有助於進行 Compose 測試的某些方面。