@TestfunandroidViewInteropTest(){// Check the initial state of a TextView that depends on a Compose state.Espresso.onView(withText("Hello Views")).check(matches(isDisplayed()))// Click on the Compose button that changes the state.composeTestRule.onNodeWithText("Click here").performClick()// Check the new value.Espresso.onView(withText("Hello Compose")).check(matches(isDisplayed()))}
Scaffold(// Enables for all composables in the hierarchy.modifier=Modifier.semantics{testTagsAsResourceId=true}){// Modifier.testTag is accessible from UiAutomator for composables nested here.LazyColumn(modifier=Modifier.testTag("myLazyColumn")){// Content}}
任何具有 Modifier.testTag(tag) 的可组合项都可通过使用 By.res(resourceName) 并利用相同的 tag 作为 resourceName 的方式访问。
valdevice=UiDevice.getInstance(getInstrumentation())vallazyColumn:UiObject2=device.findObject(By.res("myLazyColumn"))// Some interaction with the lazyColumn.
[null,null,["最后更新时间 (UTC):2025-08-21。"],[],[],null,["# Interoperability\n\nCompose integrates with common testing frameworks.\n\nInteroperability with Espresso\n------------------------------\n\nIn a hybrid app, you can find Compose components inside view hierarchies and\nviews inside Compose composables (via the [`AndroidView`](/reference/kotlin/androidx/compose/ui/viewinterop/package-summary#AndroidView(kotlin.Function1,androidx.compose.ui.Modifier,kotlin.Function1)) composable).\n\nThere are no special steps needed to match either type. You match views with\nEspresso's [`onView`](/reference/androidx/test/espresso/Espresso#onView(org.hamcrest.Matcher%3Candroid.view.View%3E)), and Compose elements with the [`ComposeTestRule`](/reference/kotlin/androidx/compose/ui/test/junit4/ComposeTestRule). \n\n @Test\n fun androidViewInteropTest() {\n // Check the initial state of a TextView that depends on a Compose state.\n Espresso.onView(withText(\"Hello Views\")).check(matches(isDisplayed()))\n // Click on the Compose button that changes the state.\n composeTestRule.onNodeWithText(\"Click here\").performClick()\n // Check the new value.\n Espresso.onView(withText(\"Hello Compose\")).check(matches(isDisplayed()))\n }\n\nInteroperability with UiAutomator\n---------------------------------\n\nBy default, composables are accessible from [UiAutomator](/training/testing/other-components/ui-automator) only by their\nconvenient descriptors (displayed text, content description, etc.). If you want\nto access any composable that uses [`Modifier.testTag`](/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).testTag(kotlin.String)), you need to enable\nthe semantic property `testTagsAsResourceId` for the particular composable's\nsubtree. Enabling this behavior is useful for composables that don't have any\nother unique handle, such as scrollable composables (for example, `LazyColumn`).\n| **Note:** This feature is available in Jetpack Compose version 1.2.0-alpha08 and higher.\n\nEnable the semantic property only once high in your composables hierarchy to\nensure all nested composables with `Modifier.testTag` are accessible from\nUiAutomator. \n\n Scaffold(\n // Enables for all composables in the hierarchy.\n modifier = Modifier.semantics {\n testTagsAsResourceId = true\n }\n ){\n // Modifier.testTag is accessible from UiAutomator for composables nested here.\n LazyColumn(\n modifier = Modifier.testTag(\"myLazyColumn\")\n ){\n // Content\n }\n }\n\nAny composable with the `Modifier.testTag(tag)` can be accessible with the use\nof [`By.res(resourceName)`](/reference/androidx/test/uiautomator/BySelector#res) using the same `tag` as the `resourceName`.\n**Caution:** Make sure you don't use [`By.res(resourcePackage, resourceId)`](/reference/androidx/test/uiautomator/BySelector#res_1) as this formats the argument as `$resourcePackage:id/$resourceId`, which is different from `Modifier.testTag`. \n\n val device = UiDevice.getInstance(getInstrumentation())\n\n val lazyColumn: UiObject2 = device.findObject(By.res(\"myLazyColumn\"))\n // Some interaction with the lazyColumn.\n\nAdditional Resources\n--------------------\n\n- **[Test apps on Android](/training/testing)**: The main Android testing landing page provides a broader view of testing fundamentals and techniques.\n- **[Fundamentals of testing](/training/testing/fundamentals):** Learn more about the core concepts behind testing an Android app.\n- **[Local tests](/training/testing/local-tests):** You can run some tests locally, on your own workstation.\n- **[Instrumented tests](/training/testing/instrumented-tests):** It is good practice to also run instrumented tests. That is, tests that run directly on-device.\n- **[Continuous integration](/training/testing/continuous-integration):** Continuous integration lets you integrate your tests into your deployment pipeline.\n- **[Test different screen sizes](/training/testing/different-screens):** With some many devices available to users, you should test for different screen sizes.\n- **[Espresso](/training/testing/espresso)**: While intended for View-based UIs, Espresso knowledge can still be helpful for some aspects of Compose testing."]]