Espresso-Intents

Espresso-Intents é uma extensão do Espresso, que permite validação e de intents enviadas pelo do aplicativo em teste. É como Mockito, mas para intents do Android.

Caso seu app delegue funcionalidades a outros apps ou à plataforma, será possível usar Espresso-Intents para se concentrar na lógica do próprio app, supondo que outros apps ou a plataforma funcionará corretamente. Com o Espresso-Intents, você pode combinar e validar as intents enviadas ou até mesmo fornecer respostas stub no lugar respostas de intent reais.

Incluir o Espresso-Intents no projeto

No arquivo app/build.gradle do app, adicione a linha abaixo dependencies:

Groovy

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

Kotlin

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

O Espresso-Intents é compatível apenas com o Espresso 2.1+ e versão 0.3+ do Bibliotecas de teste do Android, então atualize também essas linhas:

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

Programar regras de teste

Antes de programar um teste do Espresso-Intents, configure uma IntentsTestRule. Esta é uma uma extensão da classe ActivityTestRule e facilita o uso APIs do Espresso-Intents em testes funcionais da interface. Um IntentsTestRule é inicializado. Espresso-Intents antes de cada teste anotado com @Test e lançamentos. Espresso-Intents após cada execução de teste.

O snippet de código a seguir é um exemplo de um IntentsTestRule.

Kotlin

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

Java

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

Correspondência

O Espresso-Intents permite interceptar intents de saída com base no determinados critérios de correspondência, que são definidos com o uso de matchers do Hamcrest. Hamcres permite que você:

  • usar um matcher de intent já existente: opção mais fácil, que quase sempre deve ser; preferencial.
  • implementar o próprio matcher de intent: opção mais flexível. Mais detalhes são disponíveis na seção "Criar correspondências personalizadas" no Tutorial do Hamcrest (em inglês).

O Espresso-Intents oferece a intended(). e intending() para validação de intents e stubs, respectivamente. Ambos tomam um objeto Matcher<Intent> do Hamcrest como .

O snippet de código a seguir mostra a validação que usa intents existentes correspondentes que correspondem a uma intent de saída que inicia um navegador:

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

Validar intents

O Espresso-Intents registra todos os intents que tentam iniciar atividades pelo do aplicativo em teste. Usando o método intended(), que é semelhante a Mockito.verify(), é possível declarar que uma determinada intent foi vista. No entanto, O Espresso-Intents não cria stubs de respostas para intents, a menos que você configure explicitamente. para fazer isso.

O snippet de código a seguir é um exemplo de teste que valida, mas não cria stubs respostas, uma intent de saída que inicia uma conexão externa atividade:

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

Criar stubs

Usando o método intending(), que é semelhante a Mockito.when(), é possível fornecer uma resposta stub para atividades que são iniciadas com startActivityForResult() Isso é particularmente útil para atividades externas porque não é possível manipular a interface de usuário de uma atividade externa nem controlam o ActivityResult retornado para a atividade em teste.

Os snippets de código a seguir implementam um exemplo activityResult_DisplaysContactsPhoneNumber(), que verifica se, quando um usuário inicia um "contato" atividade no app em teste, o telefone de contato número é exibido:

  1. Crie o resultado a ser retornado quando uma atividade específica for iniciada. A exemplo de teste intercepta todas as intents enviadas para "contacts" e fragmenta as respostas com um ActivityResult válido, usando o código de resultado 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. Instrua o Espresso a fornecer o objeto de resultado de stub em resposta a todas invocações dos "contatos" intent:

    Kotlin

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

    Java

    intending(toPackage("com.android.contacts")).respondWith(result);
    
  3. Verificar se a ação usada para iniciar a atividade produz o resultado esperado resultado de stub. Nesse caso, o teste de exemplo verifica se o número de telefone "123-345-6789" for retornado e exibidos quando a "atividade de contato" for lançado:

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

Este é o teste activityResult_DisplaysContactsPhoneNumber() completo:

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

Outros recursos

Para mais informações sobre o uso do Espresso-Intents em testes do Android, consulte os recursos a seguir.

Amostras