如何断言"至少有一个有条件的视图"用浓咖啡?

时间:2017-05-04 20:46:30

标签: android android-espresso

我的Android活动菜单是动态填充的,我想测试这些项目是用Espresso显示的。我知道应该至少有一个标题包含标题字符串" N"和至少一个标题字符串包含" M"的项目,例如:

  • 项目N1
  • 项目N2
  • 项目M1
  • 项目M2

我的测试异常AmbiguousViewMatcherException

openActionBarOverflowOrOptionsMenu( getInstrumentation().getTargetContext());

    // go to subitem level 1
    onView(
        allOf(
            withId(R.id.title),
            withText("Settings"),
            isDisplayed()))
                .perform(click());
    SystemClock.sleep(50);

    // go to subitem level 2
    onView(
        allOf(
            withId(R.id.title),
            withText("Item type"),
            isDisplayed()))
                .perform(click());
    SystemClock.sleep(50);

    // items are shown

    // assertions
    onView(
        allOf(withId(R.id.title),
            withText("N"),
            isDisplayed()))
                .check(matches(isDisplayed()));

    onView(
        allOf(withId(R.id.title),
            withText("M"),
            isDisplayed()))
                .check(matches(isDisplayed()));

什么是正确的断言意义&#34;至少有一个带有以下断言的视图(让我们说&#34;标题包含...&#34;)显示&#34;?< / p>

我知道我可以捕获异常,实际上这意味着测试通过,但我想做正确的事。

2 个答案:

答案 0 :(得分:1)

据我所知,这在浓缩咖啡中并不容易。您必须使用自定义匹配器来获取其中一个匹配的视图,然后执行检查。

因此,如果您使用此自定义匹配器:

public static boolean SearchValue(int search, int[] array) {

    for (int y = 0; y < 20; y++) {
        if (search == array[y]) {
            return true;
        }
    }
    return false;
}

然后您可以检查第一个带有文字“M”的视图,如:

public static Matcher<View> withIndex(final Matcher<View> matcher, final int index) {
    return new TypeSafeMatcher<View>() {
        int currentIndex = 0;

        @Override
        public void describeTo(Description description) {
            description.appendText("with index: ");
            description.appendValue(index);
            matcher.describeTo(description);
        }

        @Override
        public boolean matchesSafely(View view) {
            return matcher.matches(view) && currentIndex++ == index;
        }
    };
}

此代码取自此处:https://stackoverflow.com/a/39756832/2567799。 另一种选择是编写匹配器,它只返回第一个元素。

答案 1 :(得分:0)

在我的特定情况下,我决定捕获异常,如果没有抛出则失败:

try {
    onView(
        allOf(
            withId(R.id.title),
            withText(containsString("N")),
            isDisplayed()))
        .check(matches(isDisplayed()));
    fail("We should have multiple suitable items, so AmbiguousViewMatcherException exception should be thrown");
} catch (AmbiguousViewMatcherException e) {
    // that's ok - we have multiple items with "N" in the title
}