เอสเพรสโซ่-ความตั้งใจ

Espresso-Intents เป็นส่วนขยายของ Espresso ซึ่งช่วยให้สามารถตรวจสอบและ จำลองIntent ที่แอปพลิเคชันภายใต้การทดสอบส่งออกไป ซึ่งคล้ายกับ Mockito แต่ใช้กับ Android Intent

หากแอปมอบหมายฟังก์ชันการทำงานให้กับแอปอื่นหรือแพลตฟอร์ม คุณสามารถใช้ Espresso-Intents เพื่อมุ่งเน้นที่ตรรกะของแอปของคุณเองในขณะที่สมมติว่าแอปอื่นๆ หรือแพลตฟอร์มจะทำงานได้อย่างถูกต้อง Espresso-Intents ช่วยให้คุณจับคู่ และตรวจสอบ Intent ขาออก หรือแม้แต่ระบุการตอบกลับแบบ Stub แทน การตอบกลับ Intent จริงได้

รวม Espresso-Intents ไว้ในโปรเจ็กต์

ในไฟล์ app/build.gradle ของแอป ให้เพิ่มบรรทัดต่อไปนี้ภายใน dependencies

Groovy

androidTestImplementation 'androidx.test.espresso:espresso-intents:3.6.1'

Kotlin

androidTestImplementation('androidx.test.espresso:espresso-intents:3.6.1')

Espresso-Intents ใช้ได้กับ Espresso 2.1 ขึ้นไปและไลบรารีการทดสอบ Android เวอร์ชัน 0.3 ขึ้นไปเท่านั้น ดังนั้นโปรดตรวจสอบว่าคุณได้อัปเดตบรรทัดเหล่านั้นด้วย

Groovy

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 ในการทดสอบ UI เชิงฟังก์ชันได้ง่าย 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 ช่วยให้สามารถสกัดกั้น Intent ขาออกตามเกณฑ์การจับคู่บางอย่าง ซึ่งกำหนดโดยใช้ Hamcrest Matchers Hamcrest ช่วยให้คุณทำสิ่งต่อไปนี้ได้

  • ใช้ตัวจับคู่ความตั้งใจที่มีอยู่: ตัวเลือกที่ง่ายที่สุด ซึ่งควรเป็นตัวเลือกที่ต้องการเกือบทุกครั้ง
  • ใช้ตัวจับคู่ความตั้งใจของคุณเอง: ตัวเลือกที่ยืดหยุ่นที่สุด ดูรายละเอียดเพิ่มเติมได้ในส่วน "การเขียน Matcher ที่กำหนดเอง" ภายในบทแนะนำ Hamcrest

Espresso-Intents มีเมธอด intended() และ intending() สำหรับการตรวจสอบความตั้งใจและการ จำลองตามลำดับ ทั้งสองรับออบเจ็กต์ Hamcrest Matcher<Intent> เป็นอาร์กิวเมนต์

ข้อมูลโค้ดต่อไปนี้แสดงการตรวจสอบ Intent ที่ใช้ตัวจับคู่ Intent ที่มีอยู่ซึ่งตรงกับ 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 จะบันทึก Intent ทั้งหมดที่พยายามเปิดใช้กิจกรรมจากแอปพลิเคชันภายใต้การทดสอบ การใช้เมธอด intended() ซึ่งคล้ายกับ Mockito.verify() คุณสามารถยืนยันได้ว่าระบบเห็น Intent ที่ระบุ อย่างไรก็ตาม Espresso-Intents จะไม่จำลองการตอบกลับ Intent เว้นแต่คุณจะกำหนดค่าอย่างชัดแจ้ง ให้ทำเช่นนั้น

ข้อมูลโค้ดต่อไปนี้เป็นตัวอย่างการทดสอบที่ตรวจสอบ แต่ไม่ได้จำลอง การตอบกลับของ Intent ขาออกที่เปิดกิจกรรม "โทรศัพท์" ภายนอก

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"));
}

การจำลอง

การใช้เมธอด intending() ซึ่งคล้ายกับ Mockito.when() จะช่วยให้คุณ ระบุการตอบกลับ Stub สำหรับกิจกรรมที่เปิดตัวด้วย startActivityForResult() ได้ ซึ่งจะมีประโยชน์อย่างยิ่งสำหรับกิจกรรมภายนอก เนื่องจากคุณไม่สามารถจัดการอินเทอร์เฟซผู้ใช้ของกิจกรรมภายนอกหรือ ควบคุม ActivityResult ที่ส่งคืนไปยังกิจกรรมภายใต้การทดสอบได้

ข้อมูลโค้ดต่อไปนี้จะใช้การทดสอบตัวอย่าง activityResult_DisplaysContactsPhoneNumber() ซึ่งยืนยันว่าเมื่อผู้ใช้เปิดกิจกรรม "รายชื่อติดต่อ" ในแอปที่อยู่ระหว่างการทดสอบ ระบบจะแสดงหมายเลขโทรศัพท์ของรายชื่อติดต่อ

  1. สร้างผลลัพธ์ที่จะแสดงเมื่อเปิดใช้งานกิจกรรมที่เฉพาะเจาะจง การทดสอบตัวอย่าง จะสกัดกั้น Intent ทั้งหมดที่ส่งไปยัง "contacts" และจำลอง การตอบกลับด้วย 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 ในการตอบสนองต่อการเรียกใช้ทั้งหมดของ Intent "contacts" ดังนี้

    Kotlin

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

    Java

    intending(toPackage("com.android.contacts")).respondWith(result);
  3. ตรวจสอบว่าการดำเนินการที่ใช้เพื่อเปิดกิจกรรมสร้างผลลัพธ์ สตั๊บตามที่คาดไว้ ในกรณีนี้ การทดสอบตัวอย่างจะตรวจสอบว่าระบบแสดงหมายเลขโทรศัพท์ "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: จำลองผู้ใช้ที่ดึงข้อมูลบิตแมปโดยใช้กล้อง