Compose ComposeTestRule را ارائه میدهد که به شما امکان میدهد برای پویانماییها
بهشیوهای قطعی با کنترل کامل بر ساعت آزمایش، آزمایش بنویسید. این کار به شما امکان میدهد
مقادیر پویانمایی واسطه را درستیسنجی کنید. علاوهبراین، آزمایش میتواند سریعتر از مدت واقعی پویانمایی اجرا شود.
ComposeTestRule ساعت آزمایشی خود را بهعنوان mainClock آشکار میکند. برای کنترل ساعت در کد آزمایشیتان، میتوانید
autoAdvance دارایی را روی false تنظیم کنید. پساز شروع پویانمایی موردنظرتان برای آزمایش، ساعت را میتوانید با
advanceTimeBy به جلو ببرید.
نکتهای که در اینجا باید به آن توجه کنید این است که advanceTimeBy ساعت را دقیقاً به اندازه مدت مشخصشده جلو نمیبرد. بلکه آن را به نزدیکترین مدت زمانی که
مضرب مدت فریم است گرد میکند.
@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() }
بهینهسازی آزمایشهای پویانمایی
هنگام آزمایش پویانماییهای با وفاداری بالا، اغلب باید پیشروی خودکار را غیرفعال کنید
و بهصورت دستی از میان قابها عبور کنید تا وضعیتهای واسط کاربر میانی را تأیید کنید. برای این حلقههای
خاص فریمبهفریم، از روش runWithoutImplicitWait برای
اجرای ادعاهای خود استفاده کنید. پُرسمانهای گره استاندارد (مثل onNodeWithTag یا
fetchSemanticsNode) همگامسازیهای ضمنی را راهاندازی میکنند که وقتی
ساعت را بهصورت دستی کنترل میکنید اضافی هستند، بنابراین دور زدن آنها
زمانهای اجرای آزمایش را بهطور قابلتوجهی تسریع میکند.
رهنمودهای استفاده
- مدیریت دستی ساعت: وقتی
mainClock.autoAdvanceرویfalseتنظیم شده است و واسط کاربر در وضعیت شناختهشده و پایداری برای قاب کنونی قرار دارد، از این API استفاده کنید. - اجرای رشته میانای کاربر: برای اطمینان از پایداری درخت میانای کاربر،
runWithoutImplicitWaitرا در رشته میانای کاربر، مثلاً باrunOnUiThread، فراخوانی کنید. اجرای آن در رشته واسط کاربر، آزمایش شما را درمعرض شرایط مسابقه و خواندن وضعیت قدیمی قرار میدهد. - ادعاهای فقط خواندنی: این بلوک باید دقیقاً حاوی ادعاهای فقط خواندنی باشد. هر کنشی که وضعیت را تغییر میدهد باید خارج از این بلوک انجام شود.
مثال
@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) } } } }
توصیهشده برای شما
- توجه: نوشتار پیوند وقتی جاوا اسکریپت خاموش است نمایش داده میشود
- آزمایش کردن چیدمان «نوشتن»
- ملاحظات دیگر
- سفارشیسازی کردن پویانماییها