Compose, test saati üzerinde tam kontrol sahibi olarak animasyonlar için deterministik bir şekilde testler yazmanıza olanak tanıyan ComposeTestRule sunar. Bu sayede ara animasyon değerlerini doğrulayabilirsiniz. Ayrıca test, animasyonun gerçek süresinden daha hızlı çalışabilir.
ComposeTestRule, test saatini mainClock olarak gösterir. Test kodunuzda saati kontrol etmek için autoAdvance özelliğini "false" olarak ayarlayabilirsiniz. Test etmek istediğiniz animasyonu başlattıktan sonra saat advanceTimeBy ile ileri alınabilir.
Burada dikkat edilmesi gereken nokta, advanceTimeBy işlevinin saati tam olarak belirtilen süre kadar ileri almamasıdır. Bunun yerine, kare süresinin katı olan en yakın süreye yuvarlar.
@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() }
Animasyon testlerini optimize etme
Yüksek kaliteli animasyonları test ederken genellikle otomatik ilerlemeyi devre dışı bırakmanız ve ara kullanıcı arayüzü durumlarını onaylamak için kareleri manuel olarak ilerletmeniz gerekir. Bu kare kare döngüler için runWithoutImplicitWait yöntemini kullanarak onaylarınızı yürütün. Standart düğüm sorguları (onNodeWithTag veya fetchSemanticsNode gibi), saati manuel olarak kontrol ettiğinizde gereksiz olan dolaylı senkronizasyonları tetikler. Bu nedenle, bunları atlamak test çalışma sürelerinizi önemli ölçüde hızlandırır.
Kullanım talimatları
- Manuel saat yönetimi:
mainClock.autoAdvance,falseolarak ayarlandığında ve kullanıcı arayüzü mevcut kare için bilinen, kararlı bir durumdayken bu API'yi kullanın. - Kullanıcı arayüzü iş parçacığı yürütme: Kullanıcı arayüzü ağacının kararlılığını sağlamak için kullanıcı arayüzü iş parçacığında
runWithoutImplicitWaityöntemini çağırın (ör.runOnUiThreadile). Testi kullanıcı arayüzü iş parçacığının dışında çalıştırmak, testinizi yarışma durumlarına ve eski durum okumalarına maruz bırakır. - Salt okunur onaylar: Blok, kesinlikle salt okunur onaylar içermelidir. Durumu değiştiren tüm işlemler bu bloğun dışında gerçekleştirilmelidir.
Örnek
@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) } } } }
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir.
- Compose düzeninizi test etme
- Dikkat edilmesi gereken diğer noktalar
- Animasyonları özelleştirme