Espresso:匹配对话框下的视图 [英] Espresso: match a view under a dialog

查看:28
本文介绍了Espresso:匹配对话框下的视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的测试用例相当简单:在主活动视图上,我有一个抽屉.此抽屉中的一个菜单项会打开一个对话框.我想断言,单击此菜单项,在打开对话框之前关闭抽屉.

My test case is fairly simple: on the main activity view, I have a drawer. One menu item in this drawer opens a dialog. I want to assert that, this menu item is clicked, the drawer is closed before the dialog is opened.

这是我现在所拥有的:

// 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()))

请注意,我还不想关闭对话框.因为目标是在对话框显示之前/期间断言抽屉已关闭.

Note that I don't want to dismiss the dialog yet. Because the goal is to assert that the drawer was closed before/during the display of the dialog.

问题是最后一条指令将引发 NoMatchingViewException 因为抽屉似乎不再在视图层次结构中.看起来显示对话框使它成为视图层次结构的新根.不过,我知道活动视图存在于某处.我想知道,在这种情况下,如何匹配显示对话框下的 vie.

The problem is the last instruction will rise a NoMatchingViewException as the drawer doesn't seem to be in the view herarchy anymore. It looks like displaying the dialog make it the new root of the view hirarchy. Still, I know that the activity view exists somewhere. I'd like to know, in this case, how to match the vie under the dialog when it is shown.

推荐答案

这是一个非常好的问题,我很惊讶之前没有在其他任何地方提出/讨论过.

This is a really good question and I am surprised it hasn't been asked/discussed anywhere else before.

您的推理是正确的,当对话框出现时,视图层次结构会发生变化,因此 onView(withId(R.id.activity_main_navigation_drawer)) 给出 NoMatchingViewException.在打开对话框之前将其分配给 ViewInteraction 对象也无济于事,因为即使您想使用旧对象(使用旧视图层次结构)

Your reasoning is correct, when the dialog appears the view hierarchy changes so onView(withId(R.id.activity_main_navigation_drawer))gives NoMatchingViewException. Also assigning it to a ViewInteractionobject before opening the dialog doesn't help since Espresso will try to match the object using the new view hierarchy even if you want to use the old object(that was matched using the old view hierarchy)

我要建议的解决方案应该适合您,据我所知,这是实现您想要的唯一方法.这有点违背 UI 测试的精神,因为我们只想模仿用户的行为并尝试以用户看到系统的方式断言事物,但我认为这个解决方案仍然可以,因为我们没有使用我们的系统代码与系统交互.(我们只用它来断言某些东西)

The solution I am gonna suggest should work for you and as far as I know is the only way to achieve what you want. This is kind of against the spirit of UI testing since we only want to imitate user's actions and try to assert things the way user see the system but I would argue this solution is still OK since we are not interacting with the system using our system code. (we only use it to assert something)

 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 种不同的方式来获取活动实例.这个取自 获取活动实例

Method for getActivityInstance(There are more than 999999 different ways to get the activity instance. This one is taken from get activity instance

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];
  }

作为个人偏好,我不喜欢使用活动实例,除非它是为了测试一些非常重要的东西,而且我真的无法通过其他方式测试它.

As a personal preference, I don't like to use the instance of activity, unless it is to test something really important and I really can't test it any other way.

这篇关于Espresso:匹配对话框下的视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆