Espresso-Intents

Espresso-Intents は Espresso の拡張機能で、 送信されるインテントのスタブ テスト対象アプリケーションです。例: <ph type="x-smartling-placeholder"></ph> Mockito。ただし、Android インテント向けです。

アプリが他のアプリやプラットフォームに機能を委任している場合は、 Espresso-Intents を使用して、自分のアプリのロジックに集中できる一方で、他のアプリを前提としている プラットフォームが正しく機能します。Espresso-Intents では、 送信インテントを検証したり、代わりにスタブ レスポンスを提供したりすることもできます。 レスポンスが返されます。

プロジェクトへの 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 以降およびバージョン 0.3 以降にのみ対応しています Android テスト ライブラリであるため、これらの行も必ず更新してください。

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 クラスの拡張であり、 UI の機能テストにおける Espresso-Intents APIIntentsTestRule が初期化される 各テストの前に @Test アノテーションを付けてリリースする Espresso-Intents 各テスト実行後の 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 マッチャーを使用して定義)ハムクレスト 次のことが可能になります。

  • 既存のインテント マッチャーを使用する: 最も簡単なオプションです。ほとんどの場合、この方法をおすすめします。 優先されます。
  • 独自のインテント マッチャーの実装: 最も自由度の高いオプションです。詳しくは 「カスタム マッチャーの作成」セクションを Hamcrest のチュートリアル

Espresso-Intents には 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-Intents は、アクティビティからアクティビティの起動を試みるすべてのインテントを記録します。 テスト対象アプリケーションです。intended() メソッドを使用します。これは次のようになります。 Mockito.verify() を使用して、特定のインテントが確認されたことをアサートできます。ただし、 Espresso-Intents は、明示的に設定しない限り、インテントへのレスポンスをスタブしません できます。

次のコード スニペットは、スタブではなく検証するテストの例です。 たとえば、外部の「電話」を起動する発信インテントに対するレスポンスをアクティビティ:

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. 特定のアクティビティが起動された際に返す結果を準備します。「 サンプルテストで「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 に指示します。 「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)));
}

参考情報

Android テストでの Espresso-Intents の使用について詳しくは、 次のリソースをご覧ください。

サンプル

  • IntentsBasicSample: intended()intending() の基本的な使用方法。
  • IntentsAdvancedSample: ユーザーがカメラを使用してビットマップを取得する操作をシミュレートします。