āχāĻ¨ā§āϟāĻžāϰāĻ…āĻĒāĻžāϰ⧇āĻŦāĻŋāϞāĻŋāϟāĻŋ

āĻ•āĻŽā§āĻĒā§‹āϜ āϏāĻžāϧāĻžāϰāĻŖ āĻĒāϰ⧀āĻ•ā§āώāĻžāϰ āĻ•āĻžāĻ āĻžāĻŽā§‹āϰ āϏāĻžāĻĨ⧇ āĻāϕ⧀āĻ­ā§‚āϤ āĻšāϝāĻŧāĨ¤

āĻāϏāĻĒā§āϰ⧇āϏ⧋āϰ āϏāĻžāĻĨ⧇ āχāĻ¨ā§āϟāĻžāϰāĻ…āĻĒāĻžāϰ⧇āĻŦāĻŋāϞāĻŋāϟāĻŋ

āĻāĻ•āϟāĻŋ āĻšāĻžāχāĻŦā§āϰāĻŋāĻĄ āĻ…ā§āϝāĻžāĻĒ⧇, āφāĻĒāύāĻŋ āĻ•āĻŽā§āĻĒā§‹āϜ āĻ•āĻŽā§āĻĒā§‹āĻœā§‡āĻŦāϞ ( AndroidView āĻ•āĻŽā§āĻĒā§‹āĻœā§‡āĻŦāϞ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡) āĻ­āĻŋāω āĻšāĻžāϝāĻŧāĻžāϰāĻžāĻ°ā§āĻ•āĻŋāϰ āĻ­āĻŋāϤāϰ⧇ āĻ•āĻŽā§āĻĒā§‹āϜ āĻ•āĻŽā§āĻĒā§‹āύ⧇āĻ¨ā§āϟ āĻāĻŦāĻ‚ āĻ•āĻŽā§āĻĒā§‹āϜ āĻ•āĻŽā§āĻĒā§‹āĻœā§‡āĻŦāϞ⧇āϰ āĻ­āĻŋāω āϖ⧁āρāĻœā§‡ āĻĒ⧇āϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤

āωāĻ­āϝāĻŧ āĻĒā§āϰāĻ•āĻžāϰ⧇āϰ āϏāĻžāĻĨ⧇ āĻŽāĻŋāϞ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āϕ⧋āύ āĻŦāĻŋāĻļ⧇āώ āĻĒāĻĻāĻ•ā§āώ⧇āĻĒ⧇āϰ āĻĒā§āϰāϝāĻŧā§‹āϜāύ āύ⧇āχāĨ¤ āφāĻĒāύāĻŋ Espresso āĻāϰ onView āϏāĻžāĻĨ⧇ āĻ­āĻŋāω āĻāĻŦāĻ‚ ComposeTestRule āϏāĻžāĻĨ⧇ āĻ•āĻŽā§āĻĒā§‹āϜ āĻāϞāĻŋāĻŽā§‡āĻ¨ā§āĻŸā§‡āϰ āϏāĻžāĻĨ⧇ āĻŽāĻŋāϞ āϰāĻžāϖ⧇āύāĨ¤

@Test
fun androidViewInteropTest() {
    // 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()))
}

UiAutomator āĻāϰ āϏāĻžāĻĨ⧇ āχāĻ¨ā§āϟāĻžāϰāĻ…āĻĒāĻžāϰ⧇āĻŦāĻŋāϞāĻŋāϟāĻŋ

āĻĄāĻŋāĻĢāĻ˛ā§āϟāϰ⧂āĻĒ⧇, āĻ•āĻŽā§āĻĒā§‹āĻœā§‡āĻŦāϞāϗ⧁āϞāĻŋ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āϤāĻžāĻĻ⧇āϰ āϏ⧁āĻŦāĻŋāϧāĻžāϜāύāĻ• āĻŦāĻ°ā§āĻŖāύāĻžāĻ•āĻžāϰ⧀ (āĻĒā§āϰāĻĻāĻ°ā§āĻļāĻŋāϤ āĻĒāĻžāĻ ā§āϝ, āĻŦāĻŋāώāϝāĻŧāĻŦāĻ¸ā§āϤ⧁āϰ āĻŦāĻŋāĻŦāϰāĻŖ āχāĻ¤ā§āϝāĻžāĻĻāĻŋ) āĻĻā§āĻŦāĻžāϰāĻž UiAutomator āĻĨ⧇āϕ⧇ āĻ…ā§āϝāĻžāĻ•ā§āϏ⧇āϏāϝ⧋āĻ—ā§āϝāĨ¤ āφāĻĒāύāĻŋ āϝāĻĻāĻŋ Modifier.testTag āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻāĻŽāύ āϕ⧋āύ⧋ āĻ•āĻŽā§āĻĒā§‹āĻœā§‡āĻŦāϞ āĻ…ā§āϝāĻžāĻ•ā§āϏ⧇āϏ āĻ•āϰāϤ⧇ āϚāĻžāύ, āϤāĻžāĻšāϞ⧇ āφāĻĒāύāĻžāϕ⧇ āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āĻ•āĻŽā§āĻĒā§‹āĻœā§‡āĻŦāϞ⧇āϰ āϏāĻžāĻŦāĻŸā§āϰāĻŋāϰ āϜāĻ¨ā§āϝ āĻļāĻŦā§āĻĻāĻžāĻ°ā§āĻĨāĻŋāĻ• āϏāĻŽā§āĻĒāĻ¤ā§āϤāĻŋ testTagsAsResourceId āϏāĻ•ā§āώāĻŽ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤ āĻāχ āφāϚāϰāĻŖāϟāĻŋ āϏāĻ•ā§āώāĻŽ āĻ•āϰāĻž āĻ•āĻŽā§āĻĒā§‹āĻœā§‡āĻŦāϞāϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ āĻĻāϰāĻ•āĻžāϰ⧀ āϝ⧇āϗ⧁āϞāĻŋāϰ āĻ…āĻ¨ā§āϝ āϕ⧋āύāĻ“ āĻ…āύāĻ¨ā§āϝ āĻšā§āϝāĻžāĻ¨ā§āĻĄā§‡āϞ āύ⧇āχ, āϝ⧇āĻŽāύ āĻ¸ā§āĻ•ā§āϰ⧋āϞāϝ⧋āĻ—ā§āϝ āĻ•āĻŽā§āĻĒā§‹āĻœā§‡āĻŦāϞ (āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, LazyColumn )āĨ¤

Modifier.testTag āϏāĻžāĻĨ⧇ āϏāĻŽāĻ¸ā§āϤ āύ⧇āĻ¸ā§āĻŸā§‡āĻĄ āĻ•āĻŽā§āĻĒā§‹āĻœā§‡āĻŦāϞ UiAutomator āĻĨ⧇āϕ⧇ āĻ…ā§āϝāĻžāĻ•ā§āϏ⧇āϏāϝ⧋āĻ—ā§āϝ āϤāĻž āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰāϤ⧇ āφāĻĒāύāĻžāϰ āĻ•āĻŽā§āĻĒā§‹āĻœā§‡āĻŦāϞ āĻ…āύ⧁āĻ•ā§āϰāĻŽā§‡āϰ āωāĻšā§āϚāϤāĻžāϝāĻŧ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻāĻ•āĻŦāĻžāϰ āĻļāĻŦā§āĻĻāĻžāĻ°ā§āĻĨāĻŋāĻ• āϏāĻŽā§āĻĒāĻ¤ā§āϤāĻŋ āϏāĻ•ā§āώāĻŽ āĻ•āϰ⧁āύāĨ¤

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) āϏāĻžāĻĨ⧇ āϝ⧇āϕ⧋āύāĻ“ āĻ•āĻŽā§āĻĒā§‹āϜ āĻ•āϰāĻž āϝāĻžāĻŦ⧇ resourceName āĻŽāϤ⧋ āĻāĻ•āχ tag āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ By.res(resourceName) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻ…ā§āϝāĻžāĻ•ā§āϏ⧇āϏāϝ⧋āĻ—ā§āϝāĨ¤

val device = UiDevice.getInstance(getInstrumentation())

val lazyColumn: UiObject2 = device.findObject(By.res("myLazyColumn"))
// Some interaction with the lazyColumn.

āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āϏāĻŽā§āĻĒāĻĻ