Matchers de visualização personalizada

O Espresso oferece várias opções para criar nossos próprios matchers de visualização personalizados e é baseado nos matchers do Hamcrest . O matcher personalizado é um conceito muito poderoso para estender a estrutura e também personalizar a estrutura de acordo com nosso gosto. Algumas das vantagens de escrever matchers personalizados são as seguintes,

  • Para explorar o recurso exclusivo de nossas próprias visualizações personalizadas

  • O matcher customizado ajuda nos casos de teste baseados em AdapterView para combinar com os diferentes tipos de dados subjacentes.

  • Para simplificar os combinadores atuais combinando recursos de vários combinadores

Podemos criar um novo matcher conforme e quando a demanda surge e é muito fácil. Vamos criar um novo matcher personalizado, que retorna um matcher para testar o id e o texto de um TextView .

O Espresso oferece as duas classes a seguir para escrever novos matchers -

  • TypeSafeMatcher

  • BoundedMatcher

Ambas as classes são semelhantes em natureza, exceto que o BoundedMatcher lida de forma transparente com a conversão do objeto para o tipo correto sem verificar manualmente o tipo correto. Criaremos um novo matcher, withIdAndText usando a classe BoundedMatcher . Vamos verificar as etapas para escrever novos matchers.

  • Adicione a dependência abaixo no arquivo app / build.gradle e sincronize-o.

dependencies {
   implementation 'androidx.test.espresso:espresso-core:3.1.1'
}
  • Crie uma nova classe para incluir nossos matchers (métodos) e marque-a como final

public final class MyMatchers {
}
  • Declare um método estático dentro da nova classe com os argumentos necessários e defina Matcher <View> como tipo de retorno.

public final class MyMatchers {
   @NonNull
   public static Matcher<View> withIdAndText(final Matcher<Integer>
   integerMatcher, final Matcher<String> stringMatcher) {
   }
}
  • Crie um novo objeto BoundedMatcher (valor de retorno também) com a assinatura abaixo dentro do método estático,

public final class MyMatchers {
   @NonNull
   public static Matcher<View> withIdAndText(final Matcher<Integer>
   integerMatcher, final Matcher<String> stringMatcher) {
      return new BoundedMatcher<View, TextView>(TextView.class) {
      };
   }
}
  • Substituir describeTo e matchesSafely métodos na BoundedMatcher objecto. describeTo tem um único argumento do tipo Descrição sem nenhum tipo de retorno e é usado para informações de erro relacionadas a matchers. MatchSafely tem um único argumento do tipo TextView com o tipo de retorno booleano e é usado para corresponder à visualização.

A versão final do código é a seguinte,

public final class MyMatchers {
   @NonNull
   public static Matcher<View> withIdAndText(final Matcher<Integer>
   integerMatcher, final Matcher<String> stringMatcher) {
      return new BoundedMatcher<View, TextView>(TextView.class) {
         @Override
         public void describeTo(final Description description) {
            description.appendText("error text: ");
            stringMatcher.describeTo(description);
            integerMatcher.describeTo(description);
         }
         @Override
         public boolean matchesSafely(final TextView textView) {
            return stringMatcher.matches(textView.getText().toString()) &&
            integerMatcher.matches(textView.getId());
         }
      };
   }
}
  • Por fim, podemos usar nosso mew matcher para escrever o caso de teste conforme apresentado abaixo,

@Test
public void view_customMatcher_isCorrect() {
   onView(withIdAndText(is((Integer) R.id.textView_hello), is((String) "Hello World!")))
      .check(matches(withText("Hello World!")));
}