Android Jetpack compose如何测试背景颜色

cut*_*iko 7 android android-testing android-jetpack-compose

我有一个设置背景颜色的可组合项,我想测试一下。

@Composable
fun MyComposableButton(
    enabledColor: Color,
    disableColor: Color,
    isEnabled: Boolean = true,
) {
    val buttonBackgroundColor = if (enabled) enabledColor else disableColor
    Button(
        ...
        enabled = enabled,
        colors = ButtonDefaults.textButtonColors(
            backgroundColor = buttonBackgroundColor
        )
    ) { ... }
}
Run Code Online (Sandbox Code Playgroud)

我期待编写如下测试:verifyEnabledBackgroundColorverifyDisabledBakcgroundColor

我在组合测试中找不到直接可用的任何断言,当尝试创建自己的断言时,我发现使用SemanticMatcther了 a SemanticNode,但构造函数是最新的内部断言,因此无法进行。

我尝试过mockColor但我做不到,根据这个答案,需要高 API 级别,这对我的项目来说是不行的。

如何测试设置可组合项的背景颜色?

cut*_*iko 7

[更新]请阅读其他答案/sf/answers/5084049631/

经过多次尝试和错误,我找到了一种方法。有一个captureImage具有色彩空间的扩展。这样,我们就可以找到颜色名称并做出同等的断言。

但它有一些限制:它是节点下方的表面,因此多个节点或渐变可能不起作用。

fun SemanticsNodeInteraction.assertBackgroundColor(expectedBackground: Color) {
    val capturedName = captureToImage().colorSpace.name
    assertEquals(expectedBackground.colorSpace.name, capturedName)
}
Run Code Online (Sandbox Code Playgroud)

我为可重用性做了扩展,例如:

composeTestRule.setContent {
    ...
}

composeTestRule.onNodeWithText(someText).assertBackgroundColor(YourColor)
Run Code Online (Sandbox Code Playgroud)

请注意,这可能会起作用,因为在测试中我们确保通过我们的主题:

composeTestRule.setContent {
    OurSuperCoolTheme { //your compose }
}
Run Code Online (Sandbox Code Playgroud)


小智 6

要纠正 cutiko接受的答案

基于 colorspace.name 验证可组合项的颜色不起作用,因为返回的值只是颜色空间的名称。换句话说,无论实际颜色如何,测试都会通过。

实际解决方案:

如果测试的目的是区分可组合项的实际颜色是否正确,例如在可组合项的颜色动态变化的情况下,我们需要使用 .readPixels 方法,它提供“打包到 Int 中的 ARGB 值”。

用法示例:

val array = IntArray(20)
composeTestRule.onNodeWithTag(TestTags.CONTENT_TEXT_FIELD_TAG).captureToImage()
            .readPixels(array, startY = 500, startX = 200, width = 5, height = 4)
array.forEach { it shouldNotBe Colors().Red.convert(ColorSpaces.Srgb).hashCode() }
array.forEach { it shouldBe Colors().Pink.convert(ColorSpaces.Srgb).hashCode() }
Run Code Online (Sandbox Code Playgroud)