Настраиваемые сопоставители представлений

Espresso предоставляет различные варианты для создания наших собственных сопоставителей видов, и он основан на сопоставлениях Hamcrest. Настраиваемый сопоставитель - это очень мощная концепция для расширения фреймворка, а также для настройки фреймворка по нашему вкусу. Некоторые из преимуществ написания пользовательских сопоставителей заключаются в следующем:

  • Чтобы использовать уникальные возможности наших собственных пользовательских представлений

  • Настраиваемый сопоставитель помогает в тестовых примерах на основе AdapterView соответствовать разным типам базовых данных.

  • Чтобы упростить текущие сопоставления путем объединения функций нескольких сопоставителей

Мы можем создать новый сопоставитель по мере необходимости, и это довольно просто. Давайте создадим новый настраиваемый сопоставитель, который возвращает сопоставление для проверки идентификатора и текста TextView .

Espresso предоставляет следующие два класса для написания новых сопоставлений:

  • TypeSafeMatcher

  • BoundedMatcher

Оба класса похожи по своей природе, за исключением того, что BoundedMatcher прозрачно обрабатывает приведение объекта к правильному типу без ручной проверки правильности типа. Мы создадим новый сопоставитель withIdAndText, используя класс BoundedMatcher . Давайте проверим шаги для написания новых сопоставителей.

  • Добавьте приведенную ниже зависимость в файл app / build.gradle и синхронизируйте ее.

dependencies {
   implementation 'androidx.test.espresso:espresso-core:3.1.1'
}
  • Создайте новый класс, чтобы включить наши сопоставители (методы) и пометить его как окончательный

public final class MyMatchers {
}
  • Объявите статический метод внутри нового класса с необходимыми аргументами и установите Matcher <View> в качестве возвращаемого типа.

public final class MyMatchers {
   @NonNull
   public static Matcher<View> withIdAndText(final Matcher<Integer>
   integerMatcher, final Matcher<String> stringMatcher) {
   }
}
  • Создайте новый объект BoundedMatcher (также возвращаемое значение) с подписью ниже внутри статического метода,

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) {
      };
   }
}
  • Переопределение describeTo и matchesSafely методы в BoundedMatcher объекта. descriptionTo имеет единственный аргумент типа Description без возвращаемого типа и используется для получения информации об ошибках, касающихся сопоставителей. MatchSafely имеет единственный аргумент типа TextView с логическим типом возврата, и он используется для сопоставления представления.

Окончательная версия кода выглядит следующим образом:

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());
         }
      };
   }
}
  • Наконец, мы можем использовать наш сопоставитель mew для написания тестового примера, как показано ниже,

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