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

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

בדרך כלל אין צורך לבצע פעולה כלשהי. אבל יש כמה מקרי קצה שכדאי להכיר.

כאשר בדיקה מסונכרנת, אפליקציית 'כתיבה' מתקדם בזמן באמצעות שעון וירטואלי. כלומר, בדיקות של כתיבה לא פועלות בזמן אמת ולכן הן יכולות לעבור בהקדם האפשרי.

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

@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()
}

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

השבתת הסנכרון האוטומטי

כשקוראים לטענת נכוֹנוּת (assertion) או לפעולה דרך ComposeTestRule, כמו assertExists(), הבדיקה שלך מסונכרנת עם ממשק המשתמש של הכתיבה. במקרים מסוימים ייתכן שתרצו להפסיק את הסנכרון הזה ולשלוט בשעון בעצמכם. לדוגמה, תוכלו לקבוע מתי לצלם צילומי מסך מדויקים של אנימציה, בשלב שבו ממשק המשתמש עדיין יהיה פעיל. כדי להשבית את הסנכרון האוטומטי, מגדירים את המאפיין autoAdvance בקובץ mainClock לערך false:

composeTestRule.mainClock.autoAdvance = false

בדרך כלל תצטרכו לקדם את הזמן בעצמכם. אפשר להתקדם שלב אחד בלבד פריים עם advanceTimeByFrame() או לפי משך זמן ספציפי עם advanceTimeBy():

composeTestRule.mainClock.advanceTimeByFrame()
composeTestRule.mainClock.advanceTimeBy(milliseconds)

משאבים שאינם פעילים

פיתוח נייטיב יכול לסנכרן את הבדיקות ואת ממשק המשתמש, כך שכל פעולה וטענת נכוֹנוּת (assertion) מתבצע במצב לא פעיל, בהמתנה או מתקדם בשעון לפי הצורך. אבל, חלק פעולות אסינכרוניות שהתוצאות שלהן משפיעות על המצב של ממשק המשתמש יכולות לרוץ בזמן שהבדיקה לא מודעת אליהם.

יוצרים את משאבי ההמתנה האלה ומירשמם בבדיקה, כדי שהם יילקחו בחשבון כשמגדירים אם האפליקציה שנבדקת עסוקה או לא. אין צורך לבצע פעולה כלשהי, אלא אם אתם צריכים לרשום משאבים נוספים במצב חוסר פעילות, למשל אם אתם מריצים משימה ברקע שלא מסונכרנת עם Espresso או Compose.

ה-API הזה דומה מאוד ל-Idling Resources של Espresso, כדי לציין הנושא בבדיקה לא פעיל או עמוס. השתמשו בכלל של כתיבת בדיקה כדי להירשם יישום של IdlingResource.

composeTestRule.registerIdlingResource(idlingResource)
composeTestRule.unregisterIdlingResource(idlingResource)

סנכרון ידני

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

הפונקציה 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 }

חשוב לזכור שהתנאי צריך לבדוק את המצב שיכול להיות מושפע מהשעון הזה (הוא פועל רק במצב 'כתיבה').

המתנה לתנאים

כל תנאי שמסתמך על עבודה חיצונית, כמו טעינת נתונים או מדידה או שרטוט (כלומר, מדידה או ציור מחוץ ל'כתיבה'), צריך להשתמש מושג כללי יותר, כמו 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): אינטגרציה רציפה (CI) מאפשרת לשלב את הבדיקות בפריסה צינור עיבוד נתונים.
  • בדיקה של גדלים שונים של מסכים: מכיוון שיש כל כך הרבה מכשירים שזמינים למשתמשים, כדאי לבדוק את האתר בגדלים שונים של מסכים.
  • Espresso: הספרייה מיועדת לממשקי משתמש מבוססי-תצוגה, אבל הידע ב-Espresso עדיין יכול לעזור בחלק מהיבטים של בדיקת Compose.