Matcher visualizzazione personalizzata

Espresso offre varie opzioni per creare i nostri abbinamenti di visualizzazione personalizzati e si basa sugli abbinamenti di Hamcrest. Il matcher personalizzato è un concetto molto potente per estendere il framework e anche per personalizzare il framework secondo i nostri gusti. Alcuni dei vantaggi di scrivere abbinamenti personalizzati sono i seguenti,

  • Per sfruttare la caratteristica unica delle nostre visualizzazioni personalizzate

  • Il Matcher personalizzato aiuta nei casi di test basati su AdapterView per abbinare i diversi tipi di dati sottostanti.

  • Per semplificare gli attuali matcher combinando le caratteristiche di più matcher

Possiamo creare un nuovo matcher non appena la domanda si presenta ed è abbastanza facile. Creiamo un nuovo matcher personalizzato, che restituisce un matcher per testare sia l'id che il testo di un TextView .

Espresso offre le seguenti due classi per scrivere nuovi matchers:

  • TypeSafeMatcher

  • BoundedMatcher

Entrambe le classi sono di natura simile, tranne per il fatto che BoundedMatcher gestisce in modo trasparente il casting dell'oggetto per correggere il tipo senza controllare manualmente il tipo corretto. Creeremo un nuovo matcher, withIdAndText utilizzando la classe BoundedMatcher . Controlliamo i passaggi per scrivere nuovi matcher.

  • Aggiungi la seguente dipendenza nel file app / build.gradle e sincronizzalo.

dependencies {
   implementation 'androidx.test.espresso:espresso-core:3.1.1'
}
  • Crea una nuova classe per includere i nostri matcher (metodi) e contrassegnala come finale

public final class MyMatchers {
}
  • Dichiarare un metodo statico all'interno della nuova classe con gli argomenti necessari e impostare Matcher <View> come tipo restituito.

public final class MyMatchers {
   @NonNull
   public static Matcher<View> withIdAndText(final Matcher<Integer>
   integerMatcher, final Matcher<String> stringMatcher) {
   }
}
  • Crea un nuovo oggetto BoundedMatcher (anche il valore restituito) con la firma sottostante all'interno del metodo statico,

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) {
      };
   }
}
  • Ignorare describeTo e matchesSafely metodi nella BoundedMatcher oggetto. Descrivere ha un singolo argomento di tipo Descrizione senza tipo restituito ed è utilizzato per le informazioni di errore riguardanti i matcher. MatchSafely ha un singolo argomento di tipo TextView con tipo restituito booleano e viene utilizzato per abbinare la vista.

La versione finale del codice è la seguente,

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());
         }
      };
   }
}
  • Infine, possiamo usare il nostro mew matcher per scrivere il test case come mostrato di seguito,

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