כברירת מחדל, בדיקות Compose מסונכרנות עם ממשק המשתמש. כשקוראים לאסרטיב או לפעולה באמצעות ComposeTestRule, הבדיקה מסונכרנת מראש, וממתינה עד שמבנה ה-UI לא פעיל.
בדרך כלל, לא צריך לבצע שום פעולה. עם זאת, יש כמה מקרים מיוחדים שחשוב להכיר.
כשמבצעים סנכרון של בדיקה, השעון הווירטואלי מקדם את הזמן באפליקציית 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(), הבדיקה מסונכרנת עם ממשק המשתמש של 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).
המתנה לתנאים
כל תנאי שתלוי בעבודה חיצונית, כמו טעינת נתונים או מדידה או ציור של Android (כלומר, מדידה או ציור חיצוניים ל-Compose), צריך להשתמש במושג כללי יותר כמו waitUntil():
composeTestRule.waitUntil(timeoutMs) { condition }
אפשר גם להשתמש באחד מwaitUntilהעוזרים:
composeTestRule.waitUntilAtLeastOneExists(matcher, timeoutMs)
composeTestRule.waitUntilDoesNotExist(matcher, timeoutMs)
composeTestRule.waitUntilExactlyOneExists(matcher, timeoutMs)
composeTestRule.waitUntilNodeCount(matcher, count, timeoutMs)
מקורות מידע נוספים
- בדיקת אפליקציות ב-Android: דף הנחיתה הראשי בנושא בדיקות ב-Android מספק סקירה רחבה יותר של עקרונות וטכניקות בדיקה.
- יסודות הבדיקה: מידע נוסף על המושגים הבסיסיים שמאחורי בדיקת אפליקציית Android.
- בדיקות מקומיות: אתם יכולים להריץ בדיקות מסוימות באופן מקומי, בתחנת העבודה שלכם.
- בדיקות עם מכשור: מומלץ להריץ גם בדיקות עם מכשור. כלומר, בדיקות שמופעלות ישירות במכשיר.
- אינטגרציה רציפה (CI): אינטגרציה רציפה מאפשרת לכם לשלב את הבדיקות בצינור הפריסה.
- בדיקה של גדלי מסך שונים: יש למשתמשים הרבה מכשירים שונים, ולכן כדאי לבדוק גדלי מסך שונים.
- Espresso: למרות שהיא מיועדת לממשקי משתמש מבוססי-View, הידע ב-Espresso עדיין יכול לעזור בחלק מההיבטים של בדיקות ב-Compose.