Compose: advanceTimeBy не работает с анимацией
у меня есть два
Box
эс и один. Нажав на
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()
(2-й).
java.lang.AssertionError: Failed: assertExists.
Reason: Expected exactly '1' node but could not find any node that satisfies: (TestTag = 'red_box')
Есть идеи, почему?
1 ответ
Некоторое первоначальное расследование показало, что анимация из
AnimatedVisibility
никогда не добавлялись в , потому чтоmeasure()
не был вызван, и анимация слайдов инициализируется во время измерения. В итоге у нас осталась пустаяTransition
что закончилось сразу. Вот почему тест провалился. Обратите внимание, что добавлениеadvanceTimeByFrame()
доadvanceTimeBy(1500)
кажется, позволяет пройти тест. Это может быть полезно для сужения причины.
- Источник — KotlingLang Slack: https://kotlinlang.slack.com/archives/CJLTWPH7S/p1644036648038349?thread_ts=1643956469.612919&cid=CJLTWPH7S
- Трекер проблем: https://issuetracker.google.com/issues/217880227