0

我有两个Boxes 和一个Button。单击Button会切换一个标志,并在这些盒子上触发AnimatedVisibility动画。

代码

@Composable
fun TestBox() {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        var flag by remember { mutableStateOf(false) }
        AnimatedVisibility(
            visible = !flag,
            enter = slideInHorizontally(animationSpec = tween(3000)) { it },
            exit = slideOutHorizontally(animationSpec = tween(3000)) { -it }
        ) {
            // Red box
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.Red)
                    .testTag("red_box"),
            ) {}
        }

        AnimatedVisibility(
            visible = flag,
            enter = slideInHorizontally(animationSpec = tween(3000)) { it },
            exit = slideOutHorizontally(animationSpec = tween(3000)) { -it }
        ) {
            // Red box
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.Green)
                    .testTag("green_box"),
            ) {}
        }

        Button(onClick = { flag = !flag }) {
            Text(text = "TOGGLE")
        }
    }
}

输出

在此处输入图像描述

现在我想编写一个测试来检查两个框是否在过渡中间可见。所以我写了一个这样的测试

class BoxAnimationTest {
    
    
    @get:Rule
    val composeRule = createComposeRule()

    @Before
    fun beforeAll() {
        composeRule.setContent {
            TestBox()
        }
    }

    @Test
    fun firstTest() {
        with(composeRule) {
            mainClock.autoAdvance = false
            onNodeWithTag("red_box").assertExists() // red box visible
            onNodeWithTag("green_box").assertDoesNotExist() // green box shouldn't be visible
            onNodeWithText("TOGGLE").performClick() // clicking toggle button
            
            mainClock.advanceTimeBy(1500) // and advance time to half of total duration (3000ms)
            onNodeWithTag("green_box").assertExists() // now both green and 
            onNodeWithTag("red_box").assertExists() // [FAILED] red should be visible
            
            mainClock.advanceTimeBy(1500) // finishing the animation
            onNodeWithTag("green_box") // now green should be visible
            onNodeWithTag("red_box").assertDoesNotExist() // but red shouldn't be
        }
    }
}

但它在onNodeWithTag("red_box").assertExists()(2nd)失败。

java.lang.AssertionError: Failed: assertExists.
Reason: Expected exactly '1' node but could not find any node that satisfies: (TestTag = 'red_box')

知道为什么吗?

4

1 回答 1

0

一些初步调查表明,动画 AnimatedVisibility从未添加到 中Transition,因为 measure()没有调用并且幻灯片动画在测量期间被初始化。结果,我们最终得到了一个空的Transition,马上就完成了。这就是测试失败的原因。请注意,添加 advanceTimeByFrame()之前advanceTimeBy(1500)似乎允许测试通过。这可能有助于缩小原因。

于 2022-02-05T05:31:50.127 回答