Espresso-Intents הוא תוסף ל-Espresso שמאפשר אימות ו-stubbing של intent שנשלחים על ידי האפליקציה שנבדקת. היא דומה ל- Mockito, אבל מיועדת ל-Android Intents.
אם האפליקציה שלכם מעבירה פונקציונליות לאפליקציות אחרות או לפלטפורמה, אתם יכולים להשתמש ב-Espresso-Intents כדי להתמקד בלוגיקה של האפליקציה שלכם, מתוך הנחה שאפליקציות אחרות או הפלטפורמה יפעלו בצורה תקינה. בעזרת Espresso-Intents, אפשר להתאים ולאמת את כוונות המשתמשים היוצאות, או אפילו לספק תשובות stub במקום תשובות כוונת משתמש בפועל.
הוספת Espresso-Intents לפרויקט
בקובץ app/build.gradle
של האפליקציה, מוסיפים את השורה הבאה בתוך
dependencies
:
גרוב
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.6.1'
Kotlin
androidTestImplementation('androidx.test.espresso:espresso-intents:3.6.1')
Espresso-Intents תואם רק ל-Espresso 2.1 ומעלה ולגרסה 0.3 ומעלה של ספריות הבדיקה של Android, לכן חשוב לעדכן גם את השורות האלה:
גרוב
androidTestImplementation 'androidx.test:runner:1.6.1' androidTestImplementation 'androidx.test:rules:1.6.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
Kotlin
androidTestImplementation('androidx.test:runner:1.6.1') androidTestImplementation('androidx.test:rules:1.6.1') androidTestImplementation('androidx.test.espresso:espresso-core:3.6.1')
כתיבת כללי בדיקה
לפני שכותבים בדיקת Espresso-Intents, צריך להגדיר IntentsTestRule
. זוהי הרחבה של המחלקה ActivityTestRule
, והיא מאפשרת להשתמש בקלות בממשקי Espresso-Intents API בבדיקות פונקציונליות של ממשק המשתמש. IntentsTestRule
מאתחל את Espresso-Intents לפני כל בדיקה שמסומנת ב-@Test
ומשחרר את Espresso-Intents אחרי כל הרצת בדיקה.
קטע הקוד הבא הוא דוגמה ל-IntentsTestRule
:
Kotlin
@get:Rule val intentsTestRule = IntentsTestRule(MyActivity::class.java)
Java
@Rule public IntentsTestRule<MyActivity> intentsTestRule = new IntentsTestRule<>(MyActivity.class);
התאמה
Espresso-Intents מאפשרת ליירט כוונות יוצאות על סמך קריטריונים מסוימים להתאמה, שמוגדרים באמצעות Hamcrest Matchers. Hamcrest מאפשרת לכם:
- שימוש בהתאמה קיימת של כוונות: האפשרות הכי פשוטה, שכמעט תמיד עדיפה.
- הטמעה של כלי משלכם להתאמת כוונות: האפשרות הכי גמישה. פרטים נוספים זמינים בקטע 'כתיבת התאמות מותאמות אישית' במדריך בנושא Hamcrest.
Espresso-Intents מציעה את השיטות intended()
ו-intending()
לאימות כוונות וליצירת stub, בהתאמה. שתי הפונקציות מקבלות אובייקט Hamcrest Matcher<Intent>
כארגומנט.
בקטע הקוד הבא מוצג אימות של Intent שמשתמש ב-Intent Matchers קיימים שתואמים ל-Intent יוצא שמתחיל דפדפן:
Kotlin
assertThat(intent).hasAction(Intent.ACTION_VIEW) assertThat(intent).categories().containsExactly(Intent.CATEGORY_BROWSABLE) assertThat(intent).hasData(Uri.parse("www.google.com")) assertThat(intent).extras().containsKey("key1") assertThat(intent).extras().string("key1").isEqualTo("value1") assertThat(intent).extras().containsKey("key2") assertThat(intent).extras().string("key2").isEqualTo("value2")
Java
assertThat(intent).hasAction(Intent.ACTION_VIEW); assertThat(intent).categories().containsExactly(Intent.CATEGORY_BROWSABLE); assertThat(intent).hasData(Uri.parse("www.google.com")); assertThat(intent).extras().containsKey("key1"); assertThat(intent).extras().string("key1").isEqualTo("value1"); assertThat(intent).extras().containsKey("key2"); assertThat(intent).extras().string("key2").isEqualTo("value2");
אימות כוונות
Espresso-Intents מתעד את כל הכוונות שמנסות להפעיל פעילויות מהאפליקציה שנבדקת. באמצעות השיטה intended()
, שדומה ל-Mockito.verify()
, אפשר לקבוע שזוהה Intent מסוים. עם זאת, Espresso-Intents לא יוצר תשובות ל-Intents אלא אם מגדירים אותו במפורש לעשות זאת.
קטע הקוד הבא הוא דוגמה לבדיקה שמאמתת כוונה יוצאת שמופעלת על ידי פעילות חיצונית של 'טלפון', אבל לא יוצרת stub לתשובות:
Kotlin
@Test fun validateIntentSentToPackage() { // User action that results in an external "phone" activity being launched. user.clickOnView(system.getView(R.id.callButton)) // Using a canned RecordedIntentMatcher to validate that an intent resolving // to the "phone" activity has been sent. intended(toPackage("com.android.phone")) }
Java
@Test public void validateIntentSentToPackage() { // User action that results in an external "phone" activity being launched. user.clickOnView(system.getView(R.id.callButton)); // Using a canned RecordedIntentMatcher to validate that an intent resolving // to the "phone" activity has been sent. intended(toPackage("com.android.phone")); }
Stubbing
באמצעות השיטה intending()
, שדומה ל-Mockito.when()
, אפשר לספק תגובה לסטאב לפעילויות שמופעלות באמצעות startActivityForResult()
. האפשרות הזו שימושית במיוחד לפעילויות חיצוניות, כי אי אפשר לשנות את ממשק המשתמש של פעילות חיצונית או לשלוט בערך ActivityResult
שמוחזר לפעילות שנבדקת.
קטעי הקוד הבאים מטמיעים בדיקת activityResult_DisplaysContactsPhoneNumber()
לדוגמה, שמוודאת שכאשר משתמש מפעיל פעילות 'יצירת קשר' באפליקציה שנבדקת, מספר הטלפון של איש הקשר מוצג:
יוצרים את התוצאה שתוחזר כשפעילות מסוימת תופעל. בבדיקה לדוגמה, כל הכוונות שנשלחות אל contacts перехватываются, והתשובות שלהן מוחלפות ב-stub עם
ActivityResult
תקין, באמצעות קוד התוצאהRESULT_OK
Kotlin
val resultData = Intent() val phoneNumber = "123-345-6789" resultData.putExtra("phone", phoneNumber) val result = Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)
Java
Intent resultData = new Intent(); String phoneNumber = "123-345-6789"; resultData.putExtra("phone", phoneNumber); ActivityResult result = new ActivityResult(Activity.RESULT_OK, resultData);
מנחים את Espresso לספק את אובייקט התוצאה של ה-stub בתגובה לכל הקריאות של כוונת 'אנשי קשר':
Kotlin
intending(toPackage("com.android.contacts")).respondWith(result)
Java
intending(toPackage("com.android.contacts")).respondWith(result);
מוודאים שהפעולה שמשמשת להפעלת הפעילות יוצרת את תוצאת ה-stub הצפויה. בדוגמה הזו, הבדיקה מוודאת שמספר הטלפון 123-345-6789 מוחזר ומוצג כשמפעילים את 'פעילות אנשי הקשר':
Kotlin
onView(withId(R.id.pickButton)).perform(click()) onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber)))
Java
onView(withId(R.id.pickButton)).perform(click()); onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber)));
הנה הבדיקה המלאה activityResult_DisplaysContactsPhoneNumber()
:
Kotlin
@Test fun activityResult_DisplaysContactsPhoneNumber() { // Build the result to return when the activity is launched. val resultData = Intent() val phoneNumber = "123-345-6789" resultData.putExtra("phone", phoneNumber) val result = Instrumentation.ActivityResult(Activity.RESULT_OK, resultData) // Set up result stubbing when an intent sent to "contacts" is seen. intending(toPackage("com.android.contacts")).respondWith(result) // User action that results in "contacts" activity being launched. // Launching activity expects phoneNumber to be returned and displayed. onView(withId(R.id.pickButton)).perform(click()) // Assert that the data we set up above is shown. onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber))) }
Java
@Test public void activityResult_DisplaysContactsPhoneNumber() { // Build the result to return when the activity is launched. Intent resultData = new Intent(); String phoneNumber = "123-345-6789"; resultData.putExtra("phone", phoneNumber); ActivityResult result = new ActivityResult(Activity.RESULT_OK, resultData); // Set up result stubbing when an intent sent to "contacts" is seen. intending(toPackage("com.android.contacts")).respondWith(result); // User action that results in "contacts" activity being launched. // Launching activity expects phoneNumber to be returned and displayed. onView(withId(R.id.pickButton)).perform(click()); // Assert that the data we set up above is shown. onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber))); }
מקורות מידע נוספים
מידע נוסף על שימוש ב-Espresso-Intents בבדיקות של Android זמין במקורות המידע הבאים.
טעימות
- IntentsBasicSample:
שימוש בסיסי ב-
intended()
וב-intending()
. - IntentsAdvancedSample: מדמה משתמש שמביא מפת סיביות באמצעות המצלמה.