Compose, test saatini tam olarak kontrol ederek animasyonlar için deterministik bir şekilde testler yazmanıza olanak tanıyan ComposeTestRule sunar. Bu sayede ara animasyon değerlerini doğrulayabilirsiniz. Ayrıca, testler animasyonun gerçek süresinden daha hızlı çalışabilir.
ComposeTestRule, test saatini mainClock olarak gösterir. Test kodunuzdaki saati kontrol etmek için autoAdvance özelliğini false olarak ayarlayabilirsiniz. Test etmek istediğiniz animasyonu başlattıktan sonra advanceTimeBy ile saati ileri alabilirsiniz.
Ancak advanceTimeBy komutunun saati tam olarak belirtilen süre kadar ileri almadığını unutmayın. 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 kareler arasında manuel olarak ilerlemeniz gerekir. Bu belirli kare kare döngüler için onaylarınızı yürütmek üzere runWithoutImplicitWait yöntemini kullanın. Standart düğüm sorguları (ör. onNodeWithTag veya fetchSemanticsNode), saati manuel olarak kontrol ettiğinizde gereksiz olan örtülü 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
runWithoutImplicitWait'ı çağırın (ör.runOnUiThreadile). Testi kullanıcı arayüzü iş parçacığı dışında çalıştırmak, yarışma durumu ve eski durum okumalarına maruz kalmasına neden olur. - Salt okunur onaylar: Blok kesinlikle salt okunur onaylar içermelidir. Durumu değiştiren tüm işlemler bu blokun dışında yapılmalıdır.
Ö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.
- Oluşturma düzeninizi test etme
- Dikkat edilmesi gereken diğer noktalar
- Animasyonları özelleştirme