What is the best way to inspect and assert that a listview is the expected size with android espresso?
I wrote this matcher, but don\'t quite know how to integrate i
Figured this out.
class Matchers {
public static Matcher<View> withListSize (final int size) {
return new TypeSafeMatcher<View> () {
@Override public boolean matchesSafely (final View view) {
return ((ListView) view).getCount () == size;
}
@Override public void describeTo (final Description description) {
description.appendText ("ListView should have " + size + " items");
}
};
}
}
If expecting one item in the list, put this in the actual test script.
onView (withId (android.R.id.list)).check (ViewAssertions.matches (Matchers.withListSize (1)));
There are two different approaches of getting items count in a list with espresso: First one is as @CoryRoy mentioned above - using TypeSafeMatcher, the other one is to use BoundedMatcher.
And because @CoryRoy already showed how to assert it, here I'd like to tell how to get(return) the number using different matchers.
public class CountHelper {
private static int count;
public static int getCountFromListUsingTypeSafeMatcher(@IdRes int listViewId) {
count = 0;
Matcher matcher = new TypeSafeMatcher<View>() {
@Override
protected boolean matchesSafely(View item) {
count = ((ListView) item).getCount();
return true;
}
@Override
public void describeTo(Description description) {
}
};
onView(withId(listViewId)).check(matches(matcher));
int result = count;
count = 0;
return result;
}
public static int getCountFromListUsingBoundedMatcher(@IdRes int listViewId) {
count = 0;
Matcher<Object> matcher = new BoundedMatcher<Object, String>(String.class) {
@Override
protected boolean matchesSafely(String item) {
count += 1;
return true;
}
@Override
public void describeTo(Description description) {
}
};
try {
// do a nonsense operation with no impact
// because ViewMatchers would only start matching when action is performed on DataInteraction
onData(matcher).inAdapterView(withId(listViewId)).perform(typeText(""));
} catch (Exception e) {
}
int result = count;
count = 0;
return result;
}
}
Also want to mention that you should use ListView#getCount()
instead of ListView#getChildCount()
:
getCount()
- number of data items owned by the Adapter, which may be larger than the number of visible views.getChildCount()
- number of children in the ViewGroup, which may be reused by the ViewGroup.