דפוסים נפוצים

אתם יכולים לבדוק את אפליקציית Compose באמצעות גישות ודפוסים מוכרים.

בדיקה בבידוד

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

זה לא אומר שצריך ליצור רק בדיקות יחידה של ממשק המשתמש. חשוב מאוד גם לבצע בדיקות UI שמתמקדות בחלקים גדולים יותר בממשק המשתמש.

גישה לפעילות ולמשאבים אחרי הגדרת תוכן משלכם

לעיתים קרובות צריך להגדיר את התוכן שנבדק באמצעות composeTestRule.setContent, וגם צריך לגשת למשאבי הפעילות. לדוגמה, כדי לוודא שטקסט מוצג תואם למשאב מחרוזת. עם זאת, אי אפשר להפעיל את setContent בכלל שנוצר באמצעות createAndroidComposeRule() אם הפעילות כבר מפעילה אותו.

דפוס נפוץ להשגת מטרה זו הוא ליצור AndroidComposeTestRule באמצעות פעילות ריקה, כמו ComponentActivity.

class MyComposeTest {

    @get:Rule
    val composeTestRule = createAndroidComposeRule<ComponentActivity>()

    @Test
    fun myTest() {
        // Start the app
        composeTestRule.setContent {
            MyAppTheme {
                MainScreen(uiState = exampleUiState, /*...*/)
            }
        }
        val continueLabel = composeTestRule.activity.getString(R.string.next)
        composeTestRule.onNodeWithText(continueLabel).performClick()
    }
}

שימו לב שצריך להוסיף את ComponentActivity לקובץ AndroidManifest.xml של האפליקציה. כדי להפעיל את התכונה הזו, מוסיפים את יחסי התלות הבאים למודול:

debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")

מאפייני סמנטיקה מותאמים אישית

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

// Creates a semantics property of type Long.
val PickedDateKey = SemanticsPropertyKey<Long>("PickedDate")
var SemanticsPropertyReceiver.pickedDate by PickedDateKey

עכשיו משתמשים במאפיין הזה במשנה semantics:

val datePickerValue by remember { mutableStateOf(0L) }
MyCustomDatePicker(
    modifier = Modifier.semantics { pickedDate = datePickerValue }
)

אפשר להשתמש ב-SemanticsMatcher.expectValue כדי לאמת את הערך של המאפיין במסגרת בדיקות:

composeTestRule
    .onNode(SemanticsMatcher.expectValue(PickedDateKey, 1445378400)) // 2015-10-21
    .assertExists()

אימות שחזור המצב

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

בעזרת הכיתה הזו אפשר לדמות את היצירה מחדש של רכיב מורכב. מומלץ במיוחד לאמת את ההטמעה של rememberSaveable.


class MyStateRestorationTests {

    @get:Rule
    val composeTestRule = createComposeRule()

    @Test
    fun onRecreation_stateIsRestored() {
        val restorationTester = StateRestorationTester(composeTestRule)

        restorationTester.setContent { MainScreen() }

        // TODO: Run actions that modify the state

        // Trigger a recreation
        restorationTester.emulateSavedInstanceStateRestore()

        // TODO: Verify that state has been correctly restored.
    }
}

בדיקת הגדרות מכשירים שונות

אפליקציות ל-Android צריכות להתאים את עצמן לתנאים משתנים רבים: גדלי חלונות, אזורים גיאוגרפיים, גדלי גופנים, עיצובים כהים ובהירים ועוד. רוב התנאים האלה נגזרים מערכי מכשיר שנשלטים על ידי המשתמש וחשופים באמצעות המכונה הנוכחית של Configuration. קשה לבדוק הגדרות שונות ישירות בבדיקה, כי הבדיקה צריכה להגדיר מאפיינים ברמת המכשיר.

DeviceConfigurationOverride הוא ממשק API לבדיקה בלבד שמאפשר לדמות הגדרות שונות של מכשירים באופן מותאם לשוק המקומי עבור תוכן @Composable שנמצא בבדיקה.

לאובייקט התומך של DeviceConfigurationOverride יש את פונקציות ההרחבה הבאות, שמבטלות את מאפייני התצורה ברמת המכשיר:

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

לדוגמה, הקוד הבא מחיל את ההחרגה DeviceConfigurationOverride.ForcedSize() כדי לשנות את הצפיפות באופן מקומי, ומאלץ את ה-composable של MyScreen להיראות בחלון גדול בפורמט לרוחב, גם אם המכשיר שבו פועל הבדיקה לא תומך ישירות בגודל החלון הזה:

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.ForcedSize(DpSize(1280.dp, 800.dp))
    ) {
        MyScreen() // Will be rendered in the space for 1280dp by 800dp without clipping.
    }
}

כדי להחיל כמה שינויים יחד, משתמשים ב-DeviceConfigurationOverride.then():

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.FontScale(1.5f) then
            DeviceConfigurationOverride.FontWeightAdjustment(200)
    ) {
        Text(text = "text with increased scale and weight")
    }
}

מקורות מידע נוספים

  • בדיקת אפליקציות ב-Android: דף הנחיתה הראשי של בדיקות Android מספק תצוגה רחבה יותר של העקרונות והשיטות הבסיסיים של בדיקות.
  • עקרונות בסיסיים של בדיקה: מידע נוסף על המושגים המרכזיים של בדיקת אפליקציות ל-Android.
  • בדיקות מקומיות: אפשר להריץ בדיקות מסוימות באופן מקומי, בתחנת העבודה שלכם.
  • בדיקות עם מכשירי מדידה: מומלץ להריץ גם בדיקות עם מכשירי מדידה. כלומר, בדיקות שפועלות ישירות במכשיר.
  • אינטגרציה רציפה (CI): אינטגרציה רציפה מאפשרת לשלב את הבדיקות בצינור עיבוד הנתונים לפריסה.
  • בדיקה של גדלים שונים של מסכים: מכיוון שיש כל כך הרבה מכשירים שזמינים למשתמשים, כדאי לבדוק את האתר בגדלים שונים של מסכים.
  • Espresso: הספרייה מיועדת לממשקי משתמש מבוססי-תצוגה, אבל הידע ב-Espresso עדיין יכול לעזור בחלק מהיבטים של בדיקת Compose.