סנכרון הבדיקות

כברירת מחדל, בדיקות Compose מסונכרנות עם ממשק המשתמש. כשקוראים לאסרטיב או לפעולה באמצעות ComposeTestRule, הבדיקה מסונכרנת מראש, וממתינה עד שממשק המשתמש לא פעיל.

בדרך כלל, לא צריך לבצע שום פעולה. עם זאת, יש כמה מקרים מיוחדים שחשוב להכיר.

כשמבצעים סנכרון של בדיקה, השעון הווירטואלי מקדם את הזמן באפליקציית 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 יכול לסנכרן בין הבדיקות לבין ממשק המשתמש, כך שכל פעולה וכל טענת נכוֹנוּת (assertion) מתבצעות במצב בלי פעילות, תוך המתנה או קידום של השעון לפי הצורך. עם זאת, אפשר להריץ ברקע פעולות אסינכרוניות שהתוצאות שלהן משפיעות על מצב ממשק המשתמש, בלי שהבדיקה תהיה מודעת להן.

כדאי ליצור ולרשום את משאבי ההמתנה לפעילות האלה בבדיקה, כדי שהם ייכללו בהחלטה אם האפליקציה שנבדקת עסוקה או בלי פעילות. אין צורך לבצע פעולה כלשהי, אלא אם אתם צריכים לרשום משאבים נוספים של חוסר פעילות. לדוגמה, אם אתם מפעילים משימה ברקע שלא מסונכרנת עם 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.