Compose menawarkan ComposeTestRule yang memungkinkan Anda menulis pengujian untuk animasi secara deterministik dengan kontrol penuh selama jam pengujian. Hal ini memungkinkan Anda
memverifikasi nilai animasi menengah. Selain itu, pengujian dapat berjalan lebih cepat dibandingkan durasi animasi yang sebenarnya.
ComposeTestRule menampilkan jam pengujian sebagai mainClock. Anda dapat menyetel properti autoAdvance ke false untuk mengontrol jam di kode pengujian. Setelah memulai animasi yang ingin Anda uji, jam dapat digerakkan dengan advanceTimeBy.
Satu hal yang perlu diperhatikan di sini adalah advanceTimeBy tidak menggerakkan jam persis dengan durasi yang ditentukan. Sebaliknya, ini membulatkannya ke durasi terdekat yang
merupakan pengali dari durasi frame.
@get:Rule val rule = createComposeRule() @Test fun testAnimationWithClock() { // Pause animations rule.mainClock.autoAdvance = false var enabled by mutableStateOf(false) rule.setContent { val color by animateColorAsState( targetValue = if (enabled) Color.Red else Color.Green, animationSpec = tween(durationMillis = 250) ) Box(Modifier.size(64.dp).background(color)) } // Initiate the animation. enabled = true // Let the animation proceed. rule.mainClock.advanceTimeBy(50L) // Compare the result with the image showing the expected result. // `assertAgainGolden` needs to be implemented in your code. rule.onRoot().captureToImage().assertAgainstGolden() }
Mengoptimalkan pengujian animasi
Saat menguji animasi fidelitas tinggi, Anda sering kali perlu menonaktifkan auto-advance dan melangkah secara manual melalui frame untuk menegaskan status UI perantara. Untuk loop frame demi frame
tertentu ini, gunakan metode runWithoutImplicitWait untuk
menjalankan pernyataan Anda. Kueri node standar (seperti onNodeWithTag atau
fetchSemanticsNode) memicu sinkronisasi implisit yang berlebihan
saat Anda mengontrol jam secara manual, sehingga melewati sinkronisasi tersebut akan mempercepat runtime pengujian secara signifikan.
Panduan penggunaan
- Pengelolaan jam manual: Gunakan API ini saat
mainClock.autoAdvanceditetapkan kefalsedan UI berada dalam status yang diketahui dan stabil untuk frame saat ini. - Eksekusi UI thread: Untuk memastikan stabilitas pohon UI, panggil
runWithoutImplicitWaitdi UI thread, seperti denganrunOnUiThread. Menjalankannya di luar UI thread akan mengekspos pengujian Anda ke kondisi race dan pembacaan status yang tidak valid. - Pernyataan hanya baca: Blok harus berisi pernyataan hanya baca saja. Tindakan apa pun yang mengubah status harus dilakukan di luar blok ini.
Contoh
@Test fun runWithoutImplicitWaitSample() = runComposeUiTest { setContent { MainScreen() } mainClock.autoAdvance = false // Trigger an animation onNodeWithText("Start Animation").performClick() // Step through the animation frame-by-frame while (hasPendingWork()) { mainClock.advanceTimeByFrame() waitForIdle() runOnUiThread { // Suppress implicit synchronization inside this block to avoid redundant // waits on each node query, making the frame assertions execute much faster. runWithoutImplicitWait { val box1 = onNodeWithTag("Box1").fetchSemanticsNode() val box2 = onNodeWithTag("Box2").fetchSemanticsNode() val box3 = onNodeWithTag("Box3").fetchSemanticsNode() // Assert the exact intermediate state of all three properties for this frame assert(box1.boundsInRoot.right <= box2.boundsInRoot.left) assert(box2.boundsInRoot.right <= box3.boundsInRoot.left) } } } }
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Menguji tata letak Compose Anda
- Pertimbangan lainnya
- Menyesuaikan animasi