אתם יכולים לבדוק את אפליקציית 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()
אימות שחזור המצב
חשוב לוודא שהמצב של רכיבי ה-Composes ישוחזר בזמן היצירה מחדש של הפעילות או התהליך. מבצעים את הבדיקות האלה בלי להסתמך על יצירת מחדש של הפעילות באמצעות הכיתה 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.DarkMode()
: משנה את הגדרת המערכת לעיצוב כהה או לעיצוב בהיר.DeviceConfigurationOverride.FontScale()
: שינוי של טווח הגופן של המערכת.DeviceConfigurationOverride.FontWeightAdjustment()
: מבטלת את ההתאמה של עובי הגופן במערכת.DeviceConfigurationOverride.ForcedSize()
: מאלץ שימוש במרחב אחסון מסוים, ללא קשר לגודל המכשיר.DeviceConfigurationOverride.LayoutDirection()
: משנה את כיוון הפריסה (שמאל לימין או ימין לשמאל).DeviceConfigurationOverride.Locales()
: משנה את השפה.DeviceConfigurationOverride.RoundScreen()
: משנה את הערך אם המסך עגול.
כדי להחיל שינוי ספציפי, עוטפים את התוכן שנבדק בקריאה לפונקציה ברמה העליונה 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): אינטגרציה רציפה (CI) מאפשרת לשלב את הבדיקות בצינור עיבוד הנתונים של הפריסה.
- בדיקה של גדלים שונים של מסכים: מכיוון שיש כל כך הרבה מכשירים שזמינים למשתמשים, כדאי לבדוק את האתר בגדלים שונים של מסכים.
- Espresso: אמנם הוא מיועד לממשקי משתמש מבוססי-תצוגה, אבל הידע של Espresso עדיין יכול לעזור בהיבטים מסוימים של בדיקות הכתיבה.