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:

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

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

androidTestImplementation 'androidx.test:runner:1.6.1'
androidTestImplementation
'androidx.test:rules:1.6.1'
androidTestImplementation
'androidx.test.espresso:espresso-core:3.6.1'
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 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.

@get:Rule
val intentsTestRule = IntentsTestRule(MyActivity::class.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:

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

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

    val resultData = Intent()
    val phoneNumber = "123-345-6789"
    resultData
    .putExtra("phone", phoneNumber)
    val result = Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)
    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:

    intending(toPackage("com.android.contacts")).respondWith(result)
    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:

    onView(withId(R.id.pickButton)).perform(click())
    onView
    (withId(R.id.phoneNumber)).check(matches(withText(phoneNumber)))
    onView(withId(R.id.pickButton)).perform(click());
    onView
    (withId(R.id.phoneNumber)).check(matches(withText(phoneNumber)));

Este é o teste activityResult_DisplaysContactsPhoneNumber() completo:

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