Espresso匹配第一个元素,当许多人在层次结构中时

Beb*_*op_ 24 testing android android-espresso

我正在尝试根据我的功能编写espresso函数以匹配第一个espresso找到的元素,即使找到了多个匹配的项目.

例如:我有一个包含商品价格的单元格的列表视图.我希望能够将货币兑换成加元并验证商品价格是否为加元.

我正在使用这个功能:

    onView(anyOf(withId(R.id.product_price), withText(endsWith("CAD"))))
        .check(matches(
                isDisplayed()));
Run Code Online (Sandbox Code Playgroud)

这会抛出AmbiguousViewMatcherException.

在这种情况下,我不关心有多少或几个单元格显示CAD,我只想验证它是否显示.有没有办法让espresso在遇到符合参数的物体时立即通过此测试?

app*_*tus 29

您应该能够使用以下代码创建仅在第一个项目上匹配的自定义匹配器:

private <T> Matcher<T> first(final Matcher<T> matcher) {
    return new BaseMatcher<T>() {
        boolean isFirst = true;

        @Override
        public boolean matches(final Object item) {
            if (isFirst && matcher.matches(item)) {
                isFirst = false;
                return true;
            }

            return false;
        }

        @Override
        public void describeTo(final Description description) {
            description.appendText("should return first matching item");
        }
    };
}
Run Code Online (Sandbox Code Playgroud)


Lin*_*COL 8

我创建了这个匹配器,以防万一您有许多具有相同特征的元素,例如相同的id,并且您不仅想要第一个Element而是想要一个特定的Element。希望这可以帮助:

    private static Matcher<View> getElementFromMatchAtPosition(final Matcher<View> matcher, final int position) {
    return new BaseMatcher<View>() {
        int counter = 0;
        @Override
        public boolean matches(final Object item) {
            if (matcher.matches(item)) {
                if(counter == position) {
                    counter++;
                    return true;
                }
                counter++;
            }
            return false;
        }

        @Override
        public void describeTo(final Description description) {
            description.appendText("Element at hierarchy position "+position);
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

例:

您正在使用的库中有许多具有相同ID的按钮,您想选择第二个按钮。

  ViewInteraction colorButton = onView(
            allOf(
                    getElementFromMatchAtPosition(allOf(withId(R.id.color)), 2),
                    isDisplayed()));
    colorButton.perform(click());
Run Code Online (Sandbox Code Playgroud)