matches(not(isDisplayed()))失败,出现NoMatchingViewException异常。

103

我正在尝试测试UI视图的缺失。视图选择器如下:

public static ViewInteraction onMyTestUi() {
    return onView(withId(R.id.myTestId));
}
选择器可用于检查视图是否显示,但在检查视图未显示时会出现错误。我使用如下方式:
选择器可以用来检查一个视图是否被显示,但是当检查一个视图是否没被显示时,就会出现错误。我是这样使用的:
 onMyTestUi().check(matches(not(isDisplayed())));

但是我收到了以下错误:

com.google.android.apps.common.testing.ui.espresso.NoMatchingViewException: 找不到层次结构中与id匹配的视图:is 如果目标视图不是视图层次结构的一部分,您可能需要使用Espresso.onData从以下AdapterViews之一加载它: android.widget.ListView {...}

这很奇怪。我正在检查UI的缺失,并且预计此视图将无法找到。那么为什么Espresso会报错呢? 请建议在这里可能出了什么问题。

5个回答

195

需要使用doesNotExist()代替。在此处找到这里

如果视图存在于视图层次结构中但处于不可见状态(可见性设置为'INVISIBLE'),则使用not(isDisplayed)。但是,如果视图在视图层次结构中根本不存在(例如,可见性设置为“GONE”),则使用doesNotExist()


19
这对我没用,但 onView(withId(R.id.myTestId)).check(matches(not(isDisplayed()))); 确实有效。 - Sithu
42
这取决于应用程序。 如果你想要查看的视图在视图层次结构中存在但是不可见,那么你需要使用not(isDisplayed)。但是,如果该视图不在视图层次结构中,则需要使用doesNotExist() - user846316
1
我在布局中有一个按钮,但在onCreate中根据用户角色设置了View.GONE的可见性。那么,这是否意味着它仍然存在于视图层次结构中,只是不可见而已? - Sithu
1
如果视图从视图层次结构中消失了——这可能发生在某个操作导致转换到另一个活动时——你应该使用ViewAssertions.doesNotExist():你的示例中View.GONE是错误和误导性的。请编辑你的答案。 - metis
2
View.GONE 可以与 not(isDisplayed()) 一起使用,但无法与 doesNotExist() 一起使用。如果可见性为 GONE,则 doesNotExist 返回 true。我已经尝试了一个示例。在您提供的链接中,没有任何关于 View.GONE 的说明。 - metis
显示剩余3条评论

21

也可以使用您的方法,但类似于这样:

onView(withId(R.id.next)).check(matches(not(isDisplayed())));

19
onView(withText("")).check(doesNotExist());

7
这是部分正确的答案。只有在布局中不存在目标视图(视图层次结构不包含此视图)时才有效。但是,如果目标视图实际上存在于布局视图层次结构中,但其可见性状态为GONE或INVISIBLE,则此断言将失败。在那种情况下,断言失败的消息将说明:“android.support.test.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError: View is present in the hierarchy...”。 - Simon-Droid
没错,所以我认为你可以通过详细的视图层次结构来检查错误消息。 - Olivia Liao

14

如果您勾选了“withEffectiveVisibility”视图可见性选项,则可以尝试此选项。

    onView(withId(R.id.YOURVIEW)).check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.GONE)))

8

如果您想检查 View 是否 不可见不存在

public static ViewAssertion isNotDisplayed() {
    return new ViewAssertion() {
        @Override
        public void check(View view, NoMatchingViewException noView) {
            if (view != null && isDisplayed().matches(view)) {
                throw new AssertionError("View is present in the hierarchy and Displayed: "
                        + HumanReadables.describe(view));
            }
        }
    };
}

使用方法:

onView(withId(R.id.someView)).check(isNotDisplayed());

1
谢谢您,依我之见,这是通用的“检查视图是否从屏幕上消失”的最佳解决方案。不过需要更正一点:在我看来,正确的用法是 onView(withId(R.id.someView)).check(isNotDisplayed()); - Sterling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接