✨ 从零搭建第一个Compose测试,理解 ComposeTestRule 核心机制,验证UI状态与行为。
我们将构建一个带计数器的欢迎卡片,包含标题、点击按钮和动态文本。代码清晰分离,便于单元测试。
// GreetingCard.kt — 一个简单的可组合函数 @Composable fun GreetingCard(name: String, onGreet: () -> Unit) { var count by remember { mutableStateOf(0) } Column( modifier = Modifier.padding(16.dp).fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = "你好, $name! 👋", style = MaterialTheme.typography.headlineSmall, color = Color(0xFF4E342E) ) Text( text = "点击次数: $count", modifier = Modifier.padding(vertical = 8.dp), fontSize = 18.sp ) Button(onClick = { count++ onGreet() }) { Text("点我 +1") } } }
使用 createComposeRule() 创建测试规则,在 setContent 中加载组件,然后执行断言与交互。
// GreetingCardTest.kt — 单元测试 @RunWith(AndroidJUnit4::class) class GreetingCardTest { @get:Rule val composeTestRule = createComposeRule() @Test fun greetingCard_displaysCorrectName_andIncrementsCount() { // 准备:设置组件 var greetCount = 0 composeTestRule.setContent { GreetingCard(name = "小智", onGreet = { greetCount++ }) } // 验证:初始文本 composeTestRule .onNodeWithText("你好, 小智! 👋") .assertIsDisplayed() composeTestRule .onNodeWithText("点击次数: 0") .assertExists() // 操作:点击按钮 composeTestRule .onNodeWithText("点我 +1") .performClick() // 验证:计数更新 & 回调触发 composeTestRule .onNodeWithText("点击次数: 1") .assertExists() assertThat(greetCount).isEqualTo(1) } }
| 匹配器 / 操作 | 用途 | 示例 |
|---|---|---|
onNodeWithText("...") | 按文本查找节点 | 验证标签、按钮文字 |
assertIsDisplayed() | 断言组件可见 | 确保UI出现在屏幕上 |
assertExists() | 断言节点存在(可能不可见) | 检查后台状态文本 |
performClick() | 模拟点击 | 触发按钮、点击事件 |
onNodeWithTag() | 按semantic测试标签查找 | 配合Modifier.testTag() |
📌 测试核心三步骤
setContent 加载ComposableperformClick、performTextInput 等交互assertIsDisplayed、assertExists 验证结果💡 提示: 使用 composeTestRule.onRoot() 可打印完整UI树,调试定位节点非常方便。