Compose משתלב עם מסגרות נפוצות לבדיקות.
יכולת פעולה הדדית עם Espresso
באפליקציה היברידית, אפשר למצוא רכיבי Compose בתוך היררכיות של תצוגות ותצוגות בתוך רכיבי Compose (באמצעות רכיב ה-Composable AndroidView).
אין צורך לבצע פעולות מיוחדות כדי להתאים בין שני הסוגים. אתם מתאימים תצוגות ל-onView של Espresso, ואלמנטים של Compose ל-ComposeTestRule.
@Test
fun androidViewInteropTest() {
// Check the initial state of a TextView that depends on a Compose state.
Espresso.onView(withText("Hello Views")).check(matches(isDisplayed()))
// Click on the Compose button that changes the state.
composeTestRule.onNodeWithText("Click here").performClick()
// Check the new value.
Espresso.onView(withText("Hello Compose")).check(matches(isDisplayed()))
}
הוספת סמנטיקה בהיקף View לבדיקות של יכולת פעולה הדדית ב-Compose
הגבלת החיפושים בכתיבה לתצוגות ספציפיות
כשמעבירים ממשקי משתמש מורכבים ל-Compose, יכול להיות שתיתקלו ברכיבי Compose זהים שמוטמעים בתוך כמה רכיבי View מסורתיים של Android – למשל בתוך RecyclerView או ViewPager. בתרחישים האלה, חיפוש רגיל של יצירה כמו onNodeWithText("Save") עלול להיכשל עם השגיאה 'נמצאו כמה צמתים'.
במקום לשנות את קוד הייצור כדי להוסיף תגי בדיקה דינמיים כדי להבחין בין הרכיבים האלה, אפשר להגדיר את הבדיקה ב-Compose ישירות ל-Android View ספציפי.
משתמשים ב-onRootWithViewInteraction API בכלל הבדיקה. הפונקציה הזו מקבלת ViewInteraction של Espresso, ומאפשרת לכם להשתמש ב-Espresso כדי לבודד תצוגת מאגר ספציפי ולבצע אינטראקציות של Compose רק בהיררכיה הזו.
אינטראקציה עם פריט ברשימה
אם אתם צריכים לבצע אינטראקציה עם רכיב Compose בתוך RecyclerView
שורה ספציפית, אתם יכולים להשתמש ב-Espresso כדי לאתר את השורה, ואז להגדיר את האינטראקציה עם ה-Compose כך שתתבצע רק בשורה הזו.
המערכת מתעלמת מרכיבי יצירה זהים בכל שאר השורות.
@Test fun testComposeButtonInsideRecyclerViewItem() = runComposeUiTest { // Scroll to the desired position using Espresso Espresso.onView(withId(recyclerViewId)) .perform(RecyclerViewActions.scrollToPosition<MyViewHolder>(3)) // Define an Espresso ViewInteraction that uniquely identifies the row val rowView = Espresso.onView( allOf( withId(rootViewId), hasDescendant(withText("Item #3")) ) ) // Scope the Compose search strictly to that specific row View onRootWithViewInteraction(rowView) .onNode(hasText("Like")) .performClick() }
פתרון בעיות של דו-משמעות ב-ViewPager
אם יש בזיכרון כמה קטעים עם פריסות Compose זהות, אפשר להגדיר את היקף החיפוש למזהה התצוגה הבסיסי של הקטע הספציפי כדי למנוע אי בהירות בהתאמה.
@Test fun testComposeButtonInsideViewPagerItem() = runComposeUiTest { // Swipe to the desired page using Espresso Espresso.onView(withId(viewPagerViewId)).perform(swipeLeft()) // Identify the specific container view using Espresso val fragmentB = Espresso.onView(withId(fragmentRootViewId)) // The generic text "Save" is now unique within this view scope onRootWithViewInteraction(fragmentB) .onNode(hasText("Save")) .assertIsDisplayed() }
יכולת פעולה הדדית עם UiAutomator
כברירת מחדל, אפשר לגשת לרכיבים קומפוזביליים מ-UiAutomator רק באמצעות תיאורים נוחים (טקסט שמוצג, תיאור תוכן וכו'). אם רוצים לגשת לרכיב שאפשר להרכיב ממנו ממשק משתמש שמשתמש ב-Modifier.testTag, צריך להפעיל את המאפיין הסמנטי testTagsAsResourceId בעץ המשנה של הרכיב הספציפי שאפשר להרכיב ממנו ממשק משתמש. הפעלת ההתנהגות הזו שימושית לרכיבים שאפשר להרכיב שלא כוללים נקודת אחיזה ייחודית אחרת, כמו רכיבים שאפשר להרכיב שאפשר לגלול בהם (לדוגמה, LazyColumn).
כדי לוודא שכל רכיבי ה-Composable המקוננים עם Modifier.testTag נגישים מ-UiAutomator, צריך להפעיל את המאפיין הסמנטי רק פעם אחת ברמה גבוהה בהיררכיית רכיבי ה-Composable.
Scaffold(
// Enables for all composables in the hierarchy.
modifier = Modifier.semantics {
testTagsAsResourceId = true
}
){
// Modifier.testTag is accessible from UiAutomator for composables nested here.
LazyColumn(
modifier = Modifier.testTag("myLazyColumn")
){
// Content
}
}
כל רכיב שאפשר להוסיף לו את Modifier.testTag(tag) יכול להיות נגיש באמצעות By.res(resourceName), עם אותו tag כמו resourceName.
val device = UiDevice.getInstance(getInstrumentation())
val lazyColumn: UiObject2 = device.findObject(By.res("myLazyColumn"))
// Some interaction with the lazyColumn.
מקורות מידע נוספים
- בדיקת אפליקציות ב-Android: דף הנחיתה הראשי בנושא בדיקות ב-Android מספק סקירה רחבה יותר של עקרונות וטכניקות בדיקה.
- היסודות של בדיקות: מידע נוסף על המושגים הבסיסיים שמאחורי בדיקת אפליקציית Android.
- בדיקות מקומיות: אתם יכולים להריץ בדיקות מסוימות באופן מקומי, בתחנת העבודה שלכם.
- בדיקות עם מכשור: מומלץ להריץ גם בדיקות עם מכשור. כלומר, בדיקות שמופעלות ישירות במכשיר.
- אינטגרציה רציפה (CI): אינטגרציה רציפה מאפשרת לכם לשלב את הבדיקות בצינור הפריסה.
- בדיקה בגדלים שונים של מסכים: יש למשתמשים הרבה מכשירים שונים, ולכן כדאי לבדוק את האפליקציה בגדלים שונים של מסכים.
- Espresso: למרות שהכלי מיועד לממשקי משתמש מבוססי-View, הידע ב-Espresso יכול לעזור בחלק מהבדיקות ב-Compose.