Espresso - Asserting a TextView with async loaded

2019-03-11 08:09发布

问题:

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?

回答1:

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.



回答2:

If you're not bothered with using UiAutomator with Espresso, you could do something like this in your step 4.

UiObject object = mDevice.findObject(new UiSelector().resourceId(packageName + ":id/" + "review_box"));
object.waitForExists(5000);

https://developer.android.com/reference/android/support/test/uiautomator/UiObject.html#waitForExists(long)