sko*_*kon 6 android kotlin android-espresso android-jetpack-compose
我正在使用 Espresso 来测试在 AndroidView 可组合项中具有嵌套 ButtonView 的 Compose 屏幕。但是调用Espresso.onView(ViewMatchers.withText("Click me")).perform(ViewActions.click())不起作用,并且运行测试时不会调用 onClick 回调,导致检查是否text已更新的断言失败。
我的撰写/测试依赖项是
implementation "androidx.compose.ui:ui:1.1.1"
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:1.1.1"
debugImplementation "androidx.compose.ui:ui-tooling:1.1.1"
debugImplementation "androidx.compose.ui:ui-test-manifest:1.1.1"
我的混合 Compose 代码如下所示
// OnClick functionality works when  running app
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            SampleAppTheme {
                HybridSampleScreen()
            }
        }
    }
}
@Composable
fun HybridSampleScreen() {
    var text by rememberSaveable { mutableStateOf("Initial Text") }
    Surface(
        modifier = Modifier.fillMaxSize(),
        color = MaterialTheme.colors.background
    ) {
        Column() {
            ComposableWithAndroidButton {
                text = "I've been clicked"
            }
            Text(text)
        }
    }
}
@Composable
fun ComposableWithAndroidButton(onButtonClick: () -> Unit) {
    Column() {
        Text(text = "Hello World")
        AndroidView(factory = { context ->
            //This is an alias so I can use Button view and Button Composable in the same file
            ClassicViewButton(context).apply {
                setOnClickListener { onButtonClick.invoke() }
                text = "Click me"
            }
        })
    }
}
测试失败
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
    @get:Rule
    val composeTestRule = createComposeRule()
    @Test
    fun testAndroidViewButtonInComposable() {
        composeTestRule.setContent {
            SampleAppTheme {
                HybridSampleScreen()
            }
        }
        composeTestRule.onNodeWithText("Hello World").assertIsDisplayed()
        // The first two assertions pass so it looks like Espresso is aware that there is a clickable Button view
        Espresso.onView(ViewMatchers.withText("Click me")).check(matches(isDisplayed()))
        Espresso.onView(ViewMatchers.withText("Click me")).check(matches(isClickable()))
        Espresso.onView(ViewMatchers.withText("Click me")).perform(ViewActions.click())
        composeTestRule.waitForIdle()
        composeTestRule.onNodeWithText("I've been clicked").assertIsDisplayed()
    }
}
为了进行完整性检查,我还创建了一个完全使用可组合项的屏幕,并为其创建了一个测试,并且该测试通过了。
完整撰写屏幕
@Composable
fun FullComposeScreen() {
    var text by rememberSaveable { mutableStateOf("Initial Text") }
    Column {
        ComposableWithComposeButton {
            text = "I've been clicked"
        }
        Text(text = text)
    }
}
@Composable
fun ComposableWithComposeButton(onButtonClick: () -> Unit) {
    Column() {
        Text(text = "Hello World")
        Button(onClick = {
            onButtonClick.invoke()
        }) {
            Text(text = "I'm a composable click me")
        }
    }
}
通过测试
@Test
fun testFullComposeButtonInComposable() {
    composeTestRule.setContent {
        SampleAppTheme {
            FullComposeScreen()
        }
    }
    composeTestRule.onNodeWithText("Hello World").assertIsDisplayed()
    composeTestRule.onNodeWithText("I'm a composable click me").assertIsDisplayed()
    composeTestRule.onNodeWithText("I'm a composable click me").assertHasClickAction()
    composeTestRule.onNodeWithText("I'm a composable click me").performClick()
    composeTestRule.waitForIdle()
    composeTestRule.onNodeWithText("I've been clicked").assertIsDisplayed()
}
| 归档时间: | 
 | 
| 查看次数: | 1228 次 | 
| 最近记录: |