android.support.test.espresso.PerformException: Error performing 'load adapter data' on view

泄露秘密 提交于 2019-12-23 18:28:57

问题


I am using Espresso to test a list view that appears when I am searching for an item (like an autocomplete). The list view does not appear until the user has typed in something into the SearchView. i.e. I set the ListView to View.VISIBLE only when the user has typed something into the SearchView

I am getting this error when I try to click on text in a list view. android.support.test.espresso.PerformException: Error performing 'load adapter data' on view 'with id:'. Using onData did not work.

Adding an artificial delay works, but I am unsure if this is bad practice since it seems to defeat the purpose of methods such as onData etc.

What I've tried:

  • I've tried seeing what the Espresso test recorder does, but when I use the test recorder's code, I get the error above. I believe this is because the recorder introduces some delay.

  • I read through these StackOverflow questions but they do not resolve my issue:

    • Espresso. Error performing 'load adapter data'
    • Espresso onData Error performing 'load adapter data' on view

My Code

This code works, but I would prefer not to have to introduce an artificial delay.

public pickSuggestion(int index){

    /** artificial delay to allow list to appear. 
    This works but I shouldn't have to do this right? **/

    SystemClock.sleep(1000);

    onData(anything())
        .inAdapterView(withId(R.id.list))
        .atPosition(index)
        .onChildView(withId(R.id.mTextView))
        .perform(click());
}

回答1:


Adding an artificial delay works, but I am unsure if this is bad practice since it seems to defeat the purpose of methods such as onData etc.

Your error is provided with Espresso limitation. This framework need to run on UI thread and it 'waits' until it would be idle. It doesn't wait for loading adapter data, but waits for get idling resource

Check: http://dev.jimdo.com/2014/05/09/wait-for-it-a-deep-dive-into-espresso-s-idling-resources/

IdlingResource Reference: https://developer.android.com/reference/android/support/test/espresso/IdlingResource.html

IdlingResource Documentation: https://google.github.io/android-testing-support-library/docs/espresso/idling-resource/index.html

CountingIdlingResource: https://developer.android.com/reference/android/support/test/espresso/idling/CountingIdlingResource.html

Code like SystemClock.sleep(1000) or Thread.sleep(1000) is a bad practice because better devices don't need this amount of time and older ones need more, so your code maybe flaky, rather than fast and flexible.

The solution is to create your own Espresso IdlingResource to tell Espresso when it can perform tests without losing data and time.

Hope this will help.




回答2:


Got the same error message Error performing 'load adapter data' on view, none of the answers from these posts worked for me.

Testing RecyclerView if it has data with Espresso
Espresso onData Error performing 'load adapter data' on view
Espresso. Error performing 'load adapter data'

I ended up using the Espresso UI test recorder in Android Studio. Go to Run from the top drop down menu, then click Record Espresso Test. It will ask you to pick a device to run on, once the app is launched, manually do the ui tests you like to perform and add assertions when needed. Hit OK when done. It will generate a UI test file for you.

The code generated for clicking on an item on a RecyclerView looks like this. The heavy lifting here is the Matcher method childAtPosition() At the beginning of the test, it sleeps for 10 seconds to make sure everything are loaded, usually it doesn't take 10 seconds, you can reduce it to probably 2 seconds. An alternative is to use Espresso IdlingResource like @piotrek1543 has suggested, but that requires to add interventions(mixing test specific codes) in the production code to accommodate the testing.

@LargeTest
@RunWith(AndroidJUnit4.class)
public class MainActivityTest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);

    @Test
    public void mainActivityTest() {
        // Added a sleep statement to match the app's execution delay.
        // The recommended way to handle such scenarios is to use Espresso idling resources:
        // https://google.github.io/android-testing-support-library/docs/espresso/idling-resource/index.html
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        ViewInteraction recyclerView = onView(
                allOf(withId(R.id.recycler_view_list),
                        childAtPosition(
                                withClassName(is("android.support.constraint.ConstraintLayout")),
                                0)));
        recyclerView.perform(actionOnItemAtPosition(0, click()));
    }

    private static Matcher<View> childAtPosition(
            final Matcher<View> parentMatcher, final int position) {

        return new TypeSafeMatcher<View>() {
            @Override
            public void describeTo(Description description) {
                description.appendText("Child at position " + position + " in parent ");
                parentMatcher.describeTo(description);
            }

            @Override
            public boolean matchesSafely(View view) {
                ViewParent parent = view.getParent();
                return parent instanceof ViewGroup && parentMatcher.matches(parent)
                        && view.equals(((ViewGroup) parent).getChildAt(position));
            }
        };
    }
}

Note: The generated code by the Espresso UI test recorder is not perfect either, it works for the most of the time but not 100%



来源:https://stackoverflow.com/questions/39438901/android-support-test-espresso-performexception-error-performing-load-adapter-d

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!