Android test with Espresso IdlingResource

Issue

I’m trying to test that the AutoCompleteTextView will show the items after some word will be typed. But there is a delay between typing and showing the popup. First i was using Thread.sleep() and it was working just fine. But I know that this approach isn’t clear so I’m trying to accomplish it with IdlingResource. But it doesn’t work for me. I literally read first 5 pages of Google responses, but either I don’t understand how it should work, or I have some error in my code.

Here is the code:

static class AutocompleteShowIdlingResource implements IdlingResource {

    private Activity activity;
    private @IdRes int resId;
    private ResourceCallback resourceCallback;

    public AutocompleteShowIdlingResource(Activity activity, @IdRes int resId) {
        this.activity  activity;
        this.resId  resId;
    }

    @Override
    public String getName() {
        return this.getClass().getName() + resId;
    }

    @Override
    public boolean isIdleNow() {
        boolean idle  ((AutoCompleteTextView) activity.findViewById(resId)).getAdapter() ! null;
        Log.d(TAG, "isIdleNow: " + idle);
        if (idle) {
            resourceCallback.onTransitionToIdle();
        }
        return idle;
    }

    @Override
    public void registerIdleTransitionCallback(ResourceCallback callback) {
        this.resourceCallback  callback;

    }
}

The test itself:

    Activity activity  calibrationActivityRule.getActivity();
    onView(withId(R.id.autocomplete_occupation)).perform(typeText("dok"));
    IdlingResource idlingResource  new AutocompleteShowIdlingResource(activity, R.id.autocomplete_occupation);
    Espresso.registerIdlingResources(idlingResource);
    assertEquals(((AutoCompleteTextView) activity.findViewById(R.id.autocomplete_occupation)).getAdapter().getCount(), 3);
    Espresso.unregisterIdlingResources(idlingResource);

But the test fails on java.lang.NullPointerException when trying to call getCount() on null adapter. The log is printing

isIdleNow: false

just once, which is quite strange.

There isn’t much clear examples how to use IdlingResource, so maybe someone can make it clear for me. Thanks.

Solution

Your IdlingResource will have an effect only if you use it together with onView(…).check(…) or onData(…).check(…). Actually, the “magic” will happen in the check call – it’s the place where Espresso waits until there are no running AsyncTasks or no blocking IdlingResources.

Now let’s correct your code so that it works:

Activity activity  calibrationActivityRule.getActivity();
onView(withId(R.id.autocomplete_occupation)).perform(typeText("dok"));
IdlingResource idlingResource  new AutocompleteShowIdlingResource(activity, R.id.autocomplete_occupation);

try {
    Espresso.registerIdlingResources(idlingResource);

    //that's where Espresso will wait until the idling resource is idle
    onData(anything()).inAdapter(withId(R.id.autocomplete_occupation)).check(matches(isDisplayed()); 
finally {
    Espresso.unregisterIdlingResources(idlingResource);
}
assertEquals(((AutoCompleteTextView) activity.findViewById(R.id.autocomplete_occupation)).getAdapter().getCount(), 3);

Answered By – Anatolii

Leave a Comment