【问题标题】:Espresso: match a view under a dialogEspresso:匹配对话框下的视图
【发布时间】:2020-02-20 08:41:07
【问题描述】:

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

这是我现在拥有的:

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

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

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

【问题讨论】:

    标签: android android-espresso


    【解决方案1】:

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

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

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

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

    getActivityInstance的方法(获取activity实例的方式有999999多种,这一种取自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];
      }
    

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

    【讨论】:

    • 谢谢!它运作良好。希望这个用例将在未来的版本中得到考虑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    • 2016-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多