Espresso count elements

2020-03-20 01:04发布

Is there a way to count elements with a certain id in Espresso?

I can do onView(withId(R.id.my_id)) but then I'm stuck.

I have a LinearLayout where I inject elements (not a ListView), and I want to test how many or those are to check whether they match expected behavior.

2条回答
▲ chillily
2楼-- · 2020-03-20 01:41

This can be achieved with a custom matcher. You can define one in Kotlin in the next way:

fun withChildViewCount(count: Int, childMatcher: Matcher<View>): Matcher<View> {

    return object : BoundedMatcher<View, ViewGroup>(ViewGroup::class.java) {
        override fun matchesSafely(viewGroup: ViewGroup): Boolean {
            val matchCount = viewGroup.getChildViews()
                    .filter { childMatcher.matches(it) }
                    .count()
            return matchCount == count
        }

        override fun describeTo(description: Description) {
            description.appendText("with child count $count")
        }

    }
}
查看更多
The star\"
3楼-- · 2020-03-20 01:59

Here is the matcher that I came up with:

public static Matcher<View> withViewCount(final Matcher<View> viewMatcher, final int expectedCount) {
        return new TypeSafeMatcher<View>() {
            int actualCount = -1;

            @Override
            public void describeTo(Description description) {
                if (actualCount >= 0) {
                    description.appendText("With expected number of items: " + expectedCount);
                    description.appendText("\n With matcher: ");
                    viewMatcher.describeTo(description);
                    description.appendText("\n But got: " + actualCount);
                }
            }

            @Override
            protected boolean matchesSafely(View root) {
                actualCount = 0;
                Iterable<View> iterable = TreeIterables.breadthFirstViewTraversal(root);
                actualCount = Iterables.size(Iterables.filter(iterable, withMatcherPredicate(viewMatcher)));
                return actualCount == expectedCount;
            }
        };
    }

    private static Predicate<View> withMatcherPredicate(final Matcher<View> matcher) {
        return new Predicate<View>() {
            @Override
            public boolean apply(@Nullable View view) {
                return matcher.matches(view);
            }
        };
    }

and the usage is:

onView(isRoot()).check(matches(withViewCount(withId(R.id.anything), 5)));
查看更多
登录 后发表回答