浓缩咖啡计数元素
Espresso count elements
有没有办法在 Espresso 中计算具有特定 id 的元素?
我可以做到 onView(withId(R.id.my_id))
但后来我卡住了。
我有一个 LinearLayout,我可以在其中注入元素(而不是 ListView),我想测试有多少个元素以检查它们是否符合预期行为。
这是我想出的匹配器:
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);
}
};
}
用法是:
onView(isRoot()).check(matches(withViewCount(withId(R.id.anything), 5)));
这可以通过自定义匹配器来实现。您可以通过以下方式在 Kotlin 中定义一个:
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.children
.filter { childMatcher.matches(it) }
.count()
return matchCount == count
}
override fun describeTo(description: Description) {
description.appendText("with child count $count")
}
}
}
Be_Negative的回答有和 Kotlin 版本:
声明:
fun withViewCount(viewMatcher: Matcher<View>, expectedCount: Int): Matcher<View?> {
return object : TypeSafeMatcher<View?>() {
private var actualCount = -1
override fun describeTo(description: Description) {
when {
actualCount >= 0 -> description.also {
it.appendText("Expected items count: $expectedCount, but got: $actualCount")
}
}
}
override fun matchesSafely(root: View?): Boolean {
actualCount = TreeIterables.breadthFirstViewTraversal(root).count {
viewMatcher.matches(it)
}
return expectedCount == actualCount
}
}
}
测试中的用法,例如,检查 RadioGroup 中的 RadioButtons 计数:
onView(withId(R.id.radioGroup)).check(
matches(
withViewCount(instanceOf(RadioButton::class.java), 3)
)
)
有没有办法在 Espresso 中计算具有特定 id 的元素?
我可以做到 onView(withId(R.id.my_id))
但后来我卡住了。
我有一个 LinearLayout,我可以在其中注入元素(而不是 ListView),我想测试有多少个元素以检查它们是否符合预期行为。
这是我想出的匹配器:
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);
}
};
}
用法是:
onView(isRoot()).check(matches(withViewCount(withId(R.id.anything), 5)));
这可以通过自定义匹配器来实现。您可以通过以下方式在 Kotlin 中定义一个:
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.children
.filter { childMatcher.matches(it) }
.count()
return matchCount == count
}
override fun describeTo(description: Description) {
description.appendText("with child count $count")
}
}
}
Be_Negative的回答有和 Kotlin 版本:
声明:
fun withViewCount(viewMatcher: Matcher<View>, expectedCount: Int): Matcher<View?> {
return object : TypeSafeMatcher<View?>() {
private var actualCount = -1
override fun describeTo(description: Description) {
when {
actualCount >= 0 -> description.also {
it.appendText("Expected items count: $expectedCount, but got: $actualCount")
}
}
}
override fun matchesSafely(root: View?): Boolean {
actualCount = TreeIterables.breadthFirstViewTraversal(root).count {
viewMatcher.matches(it)
}
return expectedCount == actualCount
}
}
}
测试中的用法,例如,检查 RadioGroup 中的 RadioButtons 计数:
onView(withId(R.id.radioGroup)).check(
matches(
withViewCount(instanceOf(RadioButton::class.java), 3)
)
)