Espresso-Intents

Espresso-Intents là một tiện ích cho Espresso, cho phép xác thực và giả lập các ý định do ứng dụng đang được kiểm thử gửi đi. Nó giống như Mockito, nhưng dành cho các Intent 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 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 của bạ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.6.1'

Kotlin

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

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

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

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

Trước khi viết một kiểm thử Espresso-Intents, hãy thiết lập một IntentsTestRule. Đây là một tiện ích 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ử giao diện người dùng chức năng. IntentsTestRule sẽ khởi tạo Espresso-Intents trước mỗi lần kiểm thử được chú thích bằng @Test và phát hành Espresso-Intents sau mỗi lần kiểm thử chạy.

Đoạn mã sau đây là một 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 cách sử dụng Hamcrest Matcher. Hamcrest cho phép bạn:

  • Sử dụng một công cụ so khớp ý định hiện có: Đây là lựa chọn dễ nhất và gần như luôn được ưu tiên.
  • Triển khai trình so khớp ý định của riêng bạn: Lựa 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 các đối tượng 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 và giả lập ý định, tương ứng. Cả hai đều lấy đối tượng Hamcrest Matcher<Intent> 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 đối sánh ý định hiện có để đối sánh một ý định đi bắt đầu một 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-Intents ghi lại tất cả các ý định cố gắng khởi chạy các hoạt động từ ứng dụng đang được kiểm thử. Bằng cách sử dụng phương thức intended() (tương tự như Mockito.verify()), bạn có thể khẳng định rằng một ý định nhất định đã được nhìn thấy. Tuy nhiên, Espresso-Intents không giả lập các phản hồi cho ý định trừ phi bạn định cấu hình rõ ràng để làm như vậy.

Đoạn mã sau đây là một ví dụ về kiểm thử xác thực nhưng không tạo phản hồi giả cho một ý định gửi đi để khởi chạy một 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"));
}

Stubbing

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

Các đoạn mã sau đây triển khai một ví dụ về kiểm thử activityResult_DisplaysContactsPhoneNumber(), trong đó xác minh rằng khi người dùng chạy một hoạt động "liên hệ" trong ứng dụng đang được kiểm thử, số điện thoại liên hệ sẽ xuất hiện:

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

    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 để khởi chạy hoạt động tạo ra kết quả mô phỏng như mong đợi. Trong trường hợp này, kiểm thử ví dụ sẽ kiểm tra để đảm bảo 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)));

Sau đây là quy trình 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 Espresso-Intents trong các bài kiểm thử Android, hãy tham khảo các tài nguyên sau.

Mẫu