简体   繁体   中英

Android test with Espresso IdlingResource

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM