thedarkpassenger
thedarkpassenger

Reputation: 7348

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

I have an Activity which has two Views - which are shown depending on the network condition.

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

I have written an Espresso test for testing Network conditions. Before running the test, I manually switch off the Internet.

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

Since there is no Internet, the recycler_view is GONE, and thus it is not present in the view hierarchy. But when running the code I am not getting NoMatchingViewException. Ideally when the view is not present in the hierarchy, I should get the above exception. Instead I am getting AssertionFailedError.

What is the reason for this behavior?

Upvotes: 1

Views: 1158

Answers (2)

Leśniakiewicz
Leśniakiewicz

Reputation: 904

In my opinion is this is appropriate behavior. Your view is existing in your view hierarchy, is just not visible. You should get:

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

Upvotes: 0

R. Zagórski
R. Zagórski

Reputation: 20258

The best solution here is to look into source code of Espresso. Let's trace down, what is happening.

When calling 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) with missingViewException being null. In this line noViewException is null, therefore code goes to assertThat. The assertion is isDisplayed(), which measures global effective visibility of the view. This is where AssertionFailedError is thrown.

For asserting wherther the view is not in visible in the current layout another construction should be used:

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

or

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

More explanation about it here

Upvotes: 3

Related Questions