כוונה לאספרסו

‫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() לדוגמה, שמוודאת שכאשר משתמש מפעיל פעילות 'יצירת קשר' באפליקציה שנבדקת, מספר הטלפון של איש הקשר מוצג:

  1. יוצרים את התוצאה שתוחזר כשפעילות מסוימת תופעל. בבדיקה לדוגמה, כל הכוונות שנשלחות אל 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);
  2. מנחים את Espresso לספק את אובייקט התוצאה של ה-stub בתגובה לכל הקריאות של כוונת 'אנשי קשר':

    Kotlin

    intending(toPackage("com.android.contacts")).respondWith(result)

    Java

    intending(toPackage("com.android.contacts")).respondWith(result);
  3. מוודאים שהפעולה שמשמשת להפעלת הפעילות יוצרת את תוצאת ה-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 זמין במקורות המידע הבאים.

טעימות