Эспрессо: сопоставить вид в диалоге - PullRequest
2 голосов
/ 20 февраля 2020

Мой тестовый пример довольно прост: на главном экране активности у меня есть ящик. Один пункт меню в этом ящике открывает диалог. Я хочу утверждать, что, по этому пункту меню щелкают, ящик закрывается, прежде чем открывается диалоговое окно.

Вот что у меня сейчас:

// Opens the drawer
onView(withId(R.id.activity_main_navigation_drawer)).perform(DrawerActions.open())
// Check that the drawer is opened
onView(withId(R.id.activity_main_navigation_drawer)).check(matches(isOpen()))
// Click on the menu item that closes the drawer and display the dialog
onView(withText(R.string.title_add_subscription)).perform(click())
// Check that the drawer is now closed: this won't work
onView(withId(R.id.activity_main_navigation_drawer)).check(matches(isClosed()))

Обратите внимание, что I пока не хочу закрывать диалог . Поскольку цель состоит в том, чтобы утверждать, что ящик был закрыт до / во время отображения диалогового окна.

Проблема в том, что последняя инструкция поднимется на NoMatchingViewException, так как ящик, кажется, не находится в представлении иерархия больше Похоже, что отображение диалогового окна делает его новым root представления иерархии. Тем не менее, я знаю, что вид деятельности где-то существует. В этом случае я хотел бы знать, как сопоставить v ie в диалоговом окне, когда оно отображается.

1 Ответ

1 голос
/ 21 февраля 2020

Это действительно хороший вопрос, и я удивлен, что его раньше нигде не задавали / обсуждали.

Ваши рассуждения верны, когда появляется диалоговое окно, иерархия представлений меняется, поэтому onView(withId(R.id.activity_main_navigation_drawer)) дает исключение NoMatchingViewException , Кроме того, присвоение его объекту ViewInteraction перед открытием диалогового окна не помогает, поскольку Espresso попытается сопоставить объект с использованием новой иерархии представлений, даже если вы хотите использовать старый объект (который сопоставлялся с использованием старой иерархии представлений)

Решение, которое я собираюсь предложить, должно работать для вас, и, насколько я знаю, это единственный способ достичь того, чего вы хотите. Это отчасти противоречит духу тестирования пользовательского интерфейса, так как мы хотим только имитировать действия пользователя и пытаться утверждать вещи так, как пользователь видит систему, но я бы сказал, что это решение все еще в порядке, поскольку мы не взаимодействуем с системой с помощью нашего системного кода. , (мы используем его только для подтверждения чего-либо)

 Activity activity = getActivityInstance();
 DrawerLayout drawerLayout=(DrawerLayout) activity.findViewById((R.id.drawerlayout));
// your test code
 assertFalse(drawerLayout.isDrawerOpen(GravityCompat.START))
// your remaining test code

Метод для getActivityInstance (Существует более 999999 различных способов получения экземпляра действия. Этот взят из get экземпляр действия

private Activity getActivityInstance(){
    final Activity[] currentActivity = {null};

    getInstrumentation().runOnMainSync(new Runnable(){
      public void run(){
        Collection<Activity> resumedActivity = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED);
        Iterator<Activity> it = resumedActivity.iterator();
        currentActivity[0] = it.next();
      }
    });

    return currentActivity[0];
  }

В качестве личного предпочтения я не люблю использовать пример активности, если только он не предназначен для проверки чего-то действительно важного, и я действительно не могу проверить это любым другим способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...