I'm writing a UI test with Google Espresso for Android and I'm stuck on how to assert a TextView text, which content is asynchronously loaded from a web service. My current code is:
public class MyTest extends BaseTestCase<MyActivity>{
public void setUp() throws Exception {
// (1) Tell the activity to load 'element-to-be-loaded' from webservice
this.setActivityIntent(new Intent(Intent.ACTION_VIEW, Uri.parse("data://data/element-to-be-loaded")));
getActivity();
super.setUp();
}
public void testClickOnReviews(){
// (2) Check the element is loaded and its name is displayed
Espresso
.onView(ViewMatchers.withId(R.id.element_name))
.check(ViewAssertions.matches(ViewMatchers.withText("My Name")));
// (3) Click on the details box
Espresso
.onView(ViewMatchers.withId(R.id.details_box))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
.perform(ViewActions.click());
// (4) Wait for the details screen to open
Espresso
.onView(ViewMatchers.withId(R.id.review_box));
// Go back to element screen
Espresso.pressBack();
}
}
On (1), I inform my activity to load an element from the webservice. On (2), I'm waiting for the view asserting its content. This is the part that the test fails, because it executes before the webservice answers the app.
How can I tell Espresso to wait for a particular piece of data to appear on the screen? Or should I think in a different way to write such test?
You can handle this case by registering an IdlingResource for your web service with Espresso. Take a look at this write-up: https://developer.android.com/training/testing/espresso/idling-resource.html
Most likely, you'll want to use CountingIdlingResource (which uses a simple counter to track when something is idle). This sample test demonstrates how this can be done.