在Jetpack Compose测试中如何断言指定节点是否可滚动?
Compose 测试自定义可滚动断言实现
完整实现代码
import androidx.compose.foundation.semantics.HorizontalScrollAxis import androidx.compose.foundation.semantics.ScrollAxis import androidx.compose.foundation.semantics.VerticalScrollAxis import androidx.compose.ui.test.SemanticsMatcher import androidx.compose.ui.test.SemanticsNodeInteraction import androidx.compose.ui.test.assert fun SemanticsNodeInteraction.assertIsScrollable(): SemanticsNodeInteraction { return assert( SemanticsMatcher("Node is scrollable") { node -> // 判断是否存在可用的纵向滚动能力 val hasVerticalScroll = node.config.getOrNull(VerticalScrollAxis)?.let { it != ScrollAxis.None } == true // 判断是否存在可用的横向滚动能力 val hasHorizontalScroll = node.config.getOrNull(HorizontalScrollAxis)?.let { it != ScrollAxis.None } == true hasVerticalScroll || hasHorizontalScroll } ) }
代码说明
- Compose 系统自带的可滚动组件(LazyColumn、LazyRow、添加了
verticalScroll/horizontalScroll修饰符的布局等)会自动在语义属性中注入VerticalScrollAxis、HorizontalScrollAxis属性标识滚动能力 ScrollAxis.None代表对应方向无滚动能力,只要有任意一个方向的滚动属性不为None,就判定为可滚动节点- 如果是自定义实现的滚动组件,需要手动注入对应滚动语义属性才能被该断言检测到
原有测试代码修正
你提供的测试代码中不需要调用fetchSemanticsNode(),直接对SemanticsNodeInteraction调用扩展方法即可:
@Test fun givenEnoughItems_thenAssertListIsScrollable() { composeTestRule.setContent { BasicTheme { ScrollableComponent(items = List(1000) { "$it" }) } } // 移除多余的.fetchSemanticsNode()调用 composeTestRule.onRoot().assertIsScrollable() }
可选:定向判断滚动方向
如果需要单独校验纵向/横向滚动能力,可以实现对应扩展方法:
// 断言节点支持纵向滚动 fun SemanticsNodeInteraction.assertIsVerticallyScrollable(): SemanticsNodeInteraction { return assert( SemanticsMatcher("Node is vertically scrollable") { node -> node.config.getOrNull(VerticalScrollAxis)?.let { it != ScrollAxis.None } == true } ) } // 断言节点支持横向滚动 fun SemanticsNodeInteraction.assertIsHorizontallyScrollable(): SemanticsNodeInteraction { return assert( SemanticsMatcher("Node is horizontally scrollable") { node -> node.config.getOrNull(HorizontalScrollAxis)?.let { it != ScrollAxis.None } == true } ) }
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

