Espresso 意圖

Espresso-Intent 是 Espresso 的擴充功能,能夠驗證受測應用程式傳送的意圖並進行驗證。名稱與 Mockito 類似,但用於 Android 意圖。

如果應用程式將功能委派給其他應用程式或平台,您可以使用 Espresso-Intent 專注於自家應用程式的邏輯,並假設其他應用程式或平台可正常運作。透過 Espresso-Intent,您可以比對並驗證傳出意圖,甚至提供虛設常式回應,以取代實際意圖回應。

在專案中納入 Espresso-Intent

在應用程式的 app/build.gradle 檔案中,在 dependencies 中新增以下這行程式碼:

Groovy

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

Kotlin

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

Espresso-Intent 僅與 Espresso 2.1 以上版本和 Android 測試程式庫 0.3 以上版本相容,因此請務必一併更新這些程式碼:

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

編寫測試規則

在編寫 Espresso-Intent 測試之前,請設定 IntentsTestRule。這是 ActivityTestRule 類別的擴充功能,可輕鬆在功能性 UI 測試中使用 Espresso-Intents API。IntentsTestRule 會在每項使用 @Test 註解的測試前初始化 Espresso-Intent,並在每次執行測試後發布 Espresso-Intent。

以下程式碼片段為 IntentsTestRule 範例:

Kotlin

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

Java

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

比對符合

Espresso-Intent 可根據特定比對條件攔截傳出意圖 (使用 Hamcrest 比對器定義的特定條件)。Hamcrest 可讓您:

  • 使用現有的意圖比對器:這是最簡單且應優先採用的選項。
  • 實作您自己的意圖比對器:最具彈性的選項。詳情請參閱Hamcrest 教學課程中的「編寫自訂比對器」一節。

Espresso-Intent 分別提供 intended()intending() 方法,可用於驗證意圖及調整提示。兩者都使用 Hamcrest Matcher<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-Intent 會記錄所有嘗試從受測試的應用程式啟動活動的意圖。您可以使用與 Mockito.verify() 類似的 intended() 方法,宣告已偵測到特定意圖。不過,除非您明確設定,否則 Espresso-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"));
}

積木

使用與 Mockito.when() 類似的 intending() 方法,您可以為透過 startActivityForResult() 啟動的活動提供虛設常式回應。由於您無法操控外部活動的使用者介面,或控制返回測試中活動的 ActivityResult,因此對外部活動尤其實用。

下列程式碼片段會實作 activityResult_DisplaysContactsPhoneNumber() 測試範例,驗證當使用者在測試中的應用程式中啟動「聯絡人」活動時,系統會顯示聯絡電話號碼:

  1. 建立結果,以便在特定活動啟動時傳回。範例測試會攔截所有傳送給「聯絡人」的意圖,並使用有效的 ActivityResult 以有效的 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 提供虛設常式結果物件來回應「聯絡人」意圖的所有叫用:

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

其他資源

如要進一步瞭解如何在 Android 測試中使用 Espresso-Intent,請參閱下列資源。

範例