Espresso-Intents

Espresso-Intent là một phần mở rộng của Espresso, cho phép xác thực và xếp gọn các ý định do ứng dụng gửi đi đang được kiểm thử. Tương tự như Mockito, nhưng dành cho Ý định trên Android.

Nếu ứng dụng của bạn uỷ quyền chức năng cho các ứng dụng khác hoặc nền tảng, bạn có thể sử dụng Espresso-Intents để tập trung vào logic của ứng dụng trong khi giả định rằng các ứng dụng khác hoặc nền tảng này sẽ hoạt động đúng cách. Với Espresso-Intents, bạn có thể so khớp và xác thực các ý định gửi đi hoặc thậm chí là cung cấp các phản hồi giả lập thay cho các phản hồi thực tế về ý định.

Đưa Espresso-Intents vào dự án

Trong tệp app/build.gradle của ứng dụng, hãy thêm dòng sau vào bên trong dependencies:

Groovy

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

Kotlin

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

Espresso-Intents chỉ tương thích với Espresso 2.1+ và phiên bản 0.3+ của thư viện kiểm thử Android, vì vậy, hãy nhớ cập nhật các dòng đó:

Groovy

androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test:rules:1.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

Kotlin

androidTestImplementation('androidx.test:runner:1.4.0')
androidTestImplementation('androidx.test:rules:1.4.0')
androidTestImplementation('androidx.test.espresso:espresso-core:3.4.0')

Viết quy tắc kiểm thử

Trước khi viết chương trình kiểm thử Espresso-Intent, hãy thiết lập IntentsTestRule. Đây là phần mở rộng của lớp ActivityTestRule và giúp bạn dễ dàng sử dụng các API Espresso-Intents trong các quy trình kiểm thử chức năng trên giao diện người dùng. IntentsTestRule khởi chạy các ý định Espresso trước khi mỗi quy trình kiểm thử được chú giải bằng @Test và phát hành các ý định Espresso-Intents sau mỗi lần chạy kiểm thử.

Đoạn mã sau đây là ví dụ về IntentsTestRule:

Kotlin

@get:Rule
val intentsTestRule = IntentsTestRule(MyActivity::class.java)

Java

@Rule
public IntentsTestRule<MyActivity> intentsTestRule =
    new IntentsTestRule<>(MyActivity.class);

Trùng khớp

Espresso-Intents cung cấp khả năng chặn các ý định gửi đi dựa trên một số tiêu chí so khớp nhất định, được xác định bằng Trình so khớp Hamcrest. Hamcrest cho phép bạn:

  • Sử dụng trình so khớp ý định hiện có: Tuỳ chọn dễ nhất và hầu như luôn được ưu tiên.
  • Triển khai trình so khớp ý định của riêng bạn: Tuỳ chọn linh hoạt nhất. Bạn có thể xem thêm thông tin chi tiết trong phần "Viết trình so khớp tuỳ chỉnh" trong hướng dẫn về Hamcrest.

Espresso-Intents cung cấp các phương thức intended()intending() để xác thực ý định và loại bỏ ý định tương ứng. Cả hai đều lấy đối tượng Matcher<Intent> Hamcrest làm đối số.

Đoạn mã sau đây cho thấy quy trình xác thực ý định sử dụng các trình so khớp ý định hiện có khớp với một ý định gửi đi khởi động trình duyệt:

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

Xác thực ý định

Espresso-Intent ghi lại tất cả ý định cố gắng chạy hoạt động từ ứng dụng đang được kiểm thử. Khi sử dụng phương thức intended(), tương tự như Mockito.verify(), bạn có thể xác nhận rằng một ý định nhất định đã được nhìn thấy. Tuy nhiên, Espresso-Intents không tạo mã phản hồi cho ý định trừ phi bạn định cấu hình một cách rõ ràng để thực hiện việc đó.

Đoạn mã sau đây là một ví dụ về bài kiểm thử giúp xác thực nhưng không lấy mẫu phản hồi cho một ý định đi khởi chạy hoạt động "điện thoại" bên ngoài:

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

Rổ

Khi sử dụng phương thức intending(), tương tự như Mockito.when(), bạn có thể cung cấp phản hồi giả lập cho các hoạt động được khởi chạy bằng startActivityForResult(). Điều này đặc biệt hữu ích cho các hoạt động bên ngoài vì bạn không thể thao tác với giao diện người dùng của một hoạt động bên ngoài, cũng như không kiểm soát được ActivityResult được trả về cho hoạt động đang được kiểm thử.

Các đoạn mã sau đây triển khai một thử nghiệm activityResult_DisplaysContactsPhoneNumber() mẫu. Quá trình này xác minh rằng khi người dùng chạy một hoạt động "người liên hệ" trong ứng dụng đang được kiểm thử, số điện thoại của người liên hệ sẽ hiển thị:

  1. Tạo kết quả để trả về khi một hoạt động cụ thể được chạy. Ví dụ kiểm thử chặn mọi Ý định được gửi đến "danh bạ" và tạo mã phản hồi bằng một ActivityResult hợp lệ bằng cách sử dụng mã kết quả 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. Hướng dẫn Espresso cung cấp đối tượng kết quả mã giả lập để phản hồi tất cả lệnh gọi của ý định "contacts" (danh bạ):

    Kotlin

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

    Java

    intending(toPackage("com.android.contacts")).respondWith(result);
    
  3. Xác minh rằng thao tác dùng để chạy hoạt động tạo ra kết quả mã giả lập dự kiến. Trong trường hợp này, ví dụ kiểm thử sẽ kiểm tra xem số điện thoại "123-345-6789" được trả về và hiển thị khi "hoạt động danh bạ" được khởi chạy:

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

Dưới đây là kiểm thử activityResult_DisplaysContactsPhoneNumber() hoàn chỉnh:

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

Tài nguyên khác

Để biết thêm thông tin về cách sử dụng các ý định Espresso trong kiểm thử Android, hãy tham khảo các tài nguyên sau.

Mẫu