تستهای Compose به طور پیشفرض با رابط کاربری شما همگامسازی میشوند. وقتی یک assertion یا action را با ComposeTestRule فراخوانی میکنید، تست از قبل همگامسازی میشود و منتظر میماند تا درخت رابط کاربری بیکار شود.
معمولاً لازم نیست اقدامی انجام دهید. با این حال، موارد خاصی وجود دارد که باید از آنها مطلع باشید.
وقتی یک تست همگامسازی میشود، برنامه Compose شما با استفاده از یک ساعت مجازی به موقع پیش میرود. این یعنی تستهای Compose به صورت بلادرنگ اجرا نمیشوند، بنابراین میتوانند در سریعترین زمان ممکن اجرا شوند.
با این حال، اگر از روشهایی که تستهای شما را همگامسازی میکنند استفاده نکنید، هیچ ترکیببندی مجددی رخ نخواهد داد و رابط کاربری به صورت مکث شده به نظر میرسد.
@Test
fun counterTest() {
val myCounter = mutableStateOf(0) // State that can cause recompositions.
var lastSeenValue = 0 // Used to track recompositions.
composeTestRule.setContent {
Text(myCounter.value.toString())
lastSeenValue = myCounter.value
}
myCounter.value = 1 // The state changes, but there is no recomposition.
// Fails because nothing triggered a recomposition.
assertTrue(lastSeenValue == 1)
// Passes because the assertion triggers recomposition.
composeTestRule.onNodeWithText("1").assertExists()
}توجه داشته باشید که این الزام فقط برای سلسله مراتب Compose اعمال میشود و شامل بقیه برنامه نمیشود.
همگامسازی خودکار را غیرفعال کنید
وقتی از طریق ComposeTestRule مانند assertExists() یک assertion یا action را فراخوانی میکنید، تست شما با رابط کاربری Compose هماهنگ میشود. در برخی موارد، ممکن است بخواهید این هماهنگسازی را متوقف کنید و خودتان ساعت را کنترل کنید. به عنوان مثال، میتوانید زمان را کنترل کنید تا در نقطهای که رابط کاربری هنوز مشغول است، از یک انیمیشن اسکرینشاتهای دقیقی بگیرید. برای غیرفعال کردن هماهنگسازی خودکار، ویژگی autoAdvance را در mainClock روی false تنظیم کنید:
composeTestRule.mainClock.autoAdvance = false
معمولاً خودتان زمان را جلو میبرید. میتوانید با استفاده از advanceTimeByFrame() دقیقاً یک فریم یا با استفاده از advanceTimeBy() مدت زمان مشخصی را جلو ببرید:
composeTestRule.mainClock.advanceTimeByFrame()
composeTestRule.mainClock.advanceTimeBy(milliseconds)
منابع بلااستفاده
Compose میتواند تستها و رابط کاربری را همگامسازی کند، به طوری که هر اقدام و ادعایی در حالت بیکار انجام شود، در صورت نیاز منتظر بماند یا ساعت را جلو ببرد. با این حال، برخی از عملیات ناهمزمان که نتایج آنها بر وضعیت رابط کاربری تأثیر میگذارد، میتوانند در پسزمینه اجرا شوند در حالی که تست از آنها بیاطلاع است.
این منابع بلااستفاده را در تست خود ایجاد و ثبت کنید تا هنگام تصمیمگیری در مورد مشغول یا بیکار بودن برنامه تحت آزمایش، در نظر گرفته شوند. لازم نیست اقدامی انجام دهید، مگر اینکه نیاز به ثبت منابع بلااستفاده اضافی داشته باشید، به عنوان مثال، اگر یک کار پسزمینه را اجرا میکنید که با Espresso یا Compose هماهنگ نشده است.
این API بسیار شبیه به Idling Resources در Espresso است تا نشان دهد که آیا موضوع مورد آزمایش بیکار است یا مشغول. از قانون تست Compose برای ثبت پیادهسازی IdlingResource استفاده کنید.
composeTestRule.registerIdlingResource(idlingResource)
composeTestRule.unregisterIdlingResource(idlingResource)
همگامسازی دستی
در موارد خاص، شما باید رابط کاربری Compose را با سایر بخشهای تست یا برنامهای که در حال آزمایش آن هستید، همگامسازی کنید.
تابع waitForIdle() منتظر میماند تا Compose بیکار شود، اما این تابع به ویژگی autoAdvance وابسته است:
composeTestRule.mainClock.autoAdvance = true // Default
composeTestRule.waitForIdle() // Advances the clock until Compose is idle.
composeTestRule.mainClock.autoAdvance = false
composeTestRule.waitForIdle() // Only waits for idling resources to become idle.
توجه داشته باشید که در هر دو مورد، waitForIdle() همچنین منتظر پاسهای در حال انتظار برای ترسیم و طرحبندی میماند.
همچنین، میتوانید با استفاده از advanceTimeUntil() ساعت را تا زمانی که شرایط خاصی برقرار شود، به جلو ببرید.
composeTestRule.mainClock.advanceTimeUntil(timeoutMs) { condition }
توجه داشته باشید که شرط داده شده باید حالتی را بررسی کند که میتواند تحت تأثیر این ساعت قرار گیرد (فقط با حالت Compose کار میکند).
منتظر شرایط باشید
هر شرطی که به کار خارجی بستگی دارد، مانند بارگذاری دادهها یا اندازهگیری یا ترسیم اندروید (یعنی اندازهگیری یا ترسیم خارج از Compose)، باید از یک مفهوم کلیتر مانند waitUntil() استفاده کند:
composeTestRule.waitUntil(timeoutMs) { condition }
همچنین میتوانید از هر یک از کمکیهای waitUntil استفاده کنید:
composeTestRule.waitUntilAtLeastOneExists(matcher, timeoutMs)
composeTestRule.waitUntilDoesNotExist(matcher, timeoutMs)
composeTestRule.waitUntilExactlyOneExists(matcher, timeoutMs)
composeTestRule.waitUntilNodeCount(matcher, count, timeoutMs)
منابع اضافی
- تست برنامهها در اندروید : صفحه اصلی تست اندروید، نمای وسیعتری از اصول و تکنیکهای تست ارائه میدهد.
- اصول اولیه تست : درباره مفاهیم اصلی پشت تست یک برنامه اندروید بیشتر بدانید.
- تستهای محلی : شما میتوانید برخی از تستها را به صورت محلی، روی ایستگاه کاری خودتان اجرا کنید.
- تستهای ابزاری : اجرای تستهای ابزاری نیز روش خوبی است. یعنی تستهایی که مستقیماً روی دستگاه اجرا میشوند.
- ادغام مداوم : ادغام مداوم به شما امکان میدهد تستهای خود را در خط تولید خود ادغام کنید.
- آزمایش اندازههای مختلف صفحه نمایش : با توجه به اینکه دستگاههای زیادی در دسترس کاربران است، باید اندازههای مختلف صفحه نمایش را آزمایش کنید.
- Espresso : اگرچه برای رابطهای کاربری مبتنی بر View در نظر گرفته شده است، اما دانش Espresso همچنان میتواند برای برخی از جنبههای تست Compose مفید باشد.