当视图的可见性消失时,Espresso 不会抛出 NoMatchingViewException

Espresso not throwing NoMatchingViewException when the visibility of the view is gone

我有一个 Activity,它有两个 Views - 根据网络状况显示。

  LinearLayout recyclerView = (LinearLayout) findViewById(R.id.recycler_view);
  LinearLayout errorParent = (LinearLayout) findViewById(R.id.error_parent);

  if(Utils.isNetworkAvailable()){
      recyclerView.setVisibility(View.VISIBLE);
      errorParent.setVisibility(View.GONE);
  }else{
      recyclerView.setVisibility(View.GONE);
      errorParent.setVisibility(View.VISIBLE);
}

我已经编写了用于测试网络状况的 Espresso 测试。 运行 测试前,我手动关掉了网络。

ViewInteraction viewInteraction = onView(withId(R.id.recycler_view));
viewInteraction.check(matches(isDisplayed()));

由于没有 Internet,recycler_viewGONE,因此它不存在于视图层次结构中。但是当 运行 代码时,我没有得到 NoMatchingViewException。理想情况下,当层次结构中不存在视图时,我应该得到上述异常。相反,我得到 AssertionFailedError

这种行为的原因是什么?

这里最好的解决办法是查看 Espresso 的源代码。往下追查,到底是怎么回事。

当调用 check(final ViewAssertion viewAssert) in this line, the view is checked whether it is in the hierarchy. The exception NoMatchingViewException is not caught, because viewFinder finds the view in the hierarchy. Then the code goes to assertion. So the code goes funther to ViewAssertion's function: matches(final Matcher<? super View> viewMatcher)missingViewException 为空时。 在这line noViewException is null, therefore code goes to assertThat. The assertion is isDisplayed(), which measures global effective visibility of the view。这是抛出 AssertionFailedError 的地方。

要断言视图在当前布局中是否不可见,应使用另一个构造:

onView({Matcher<View>}).check(doesNotExist());

onView({Matcher<View>}).check(matches(not(isDisplayed())));

关于它的更多解释

我认为这是适当的行为。您的视图存在于您的视图层次结构中,只是不可见。你应该得到:

AssertionFailedWithCauseError: 'is displayed on the screen to the user' doesn't match the selected view.
Expected: is displayed on the screen to the user