Android-Espresso-当列表中存在其他对象时声明对象

时间:2018-08-05 12:39:08

标签: android listview android-espresso

我需要使用espresso或uiautomator(我接受其他建议)进行仪表化测试,以基于列表中的另一个值来验证某个值的存在。

我所看到的问题/答案都提供了有关使用列表视图中的索引或使用带有关联数字的特定标签的解决方案(基本上是同一件事)

我的问题是我不知道位置,但是我需要检查当遇到特定的String值时,该行上是否显示图像。

该列表由“自定义适配器”填充。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

经过几次尝试后,我最终做了一些自定义匹配器,只需进行一些改动即可适用于所有类型的视图。

在测试中是这样称呼的:

onView(CommonMatchers.withTextAndComparableText(R.id.tvTypeName, R.id.rlParentView, R.id.tvName, is(typeNameText), is (nameText))).check(matches(isDisplayed()));

变量: childId-我想与之进行比较的视图, parentId-两个视图的父级, comparableChildId-我想比较的视图

这里是Matcher

public static Matcher<View> withTextAndComparableText(int childId, int parentId, int comparableChildId,
        final Matcher<String>
                eventMatcher,
        final Matcher<String> parcelIdMatcher) {
    checkNotNull(eventMatcher);
    return new BoundedMatcher<View, TextView>(TextView.class) {
        @Override
        public void describeTo(Description description) {
            description.appendText("with text: ");
            eventMatcher.describeTo(description);
        }

        @Override
        public boolean matchesSafely(TextView textView) {
            if (eventMatcher.matches(textView.getText().toString()) && childId == textView.getId()) {
                TextView textViewToCompare = (TextView) checkParentAndComparableChildForValidation(parentId,
                        comparableChildId, textView, parcelIdMatcher);
                return textViewToCompare != null && parcelIdMatcher.matches(textViewToCompare.getText().toString());
            }
            return false;
        }

    };
}

然后添加下一个私有方法以首先获取父视图,然后获取可编译子视图

    private static View checkParentAndComparableChildForValidation(int parentId, int comparableChildId,
        View objectView,
        Matcher<String> parcelIdMatcher) {
    ViewParent parentView = findParentRecursively(objectView, parentId);
    Object childObject = getObjectFromParent((View) parentView, comparableChildId);

    if (childObject instanceof View) {
        return (View) childObject;
    }
    return null;
}

private static Object getObjectFromParent(View viewParent, int childId) {
    return viewParent.findViewById(childId);
}

private static ViewParent findParentRecursively(View view, int targetId) {
    if (view.getId() == targetId) {
        return (ViewParent) view;
    }
    View parent = (View) view.getParent();
    if (parent == null) {
        return null;
    }
    return findParentRecursively(parent, targetId);
}

瞧瞧!

如果要与“图像”或其他视图进行比较,则无需进行任何更改...

    public static Matcher<View> withImageAndComparableText(int childId, int parentId, int comparableChildId,
        final Matcher<String> parcelIdMatcher) {
    return new BoundedMatcher<View, ImageView>(ImageView.class) {
        @Override
        public void describeTo(Description description) {
            description.appendText("with id: " + childId);
        }

        @Override
        public boolean matchesSafely(ImageView imageView) {
            if (imageView.getId() == childId) {
                TextView textViewToCompare = (TextView) checkParentAndComparableChildForValidation(parentId,
                        comparableChildId, imageView, parcelIdMatcher);
                return textViewToCompare != null && parcelIdMatcher.matches(textViewToCompare.getText().toString());
            }

            return false;
        }

    };
}

和测试中的通话:

        onView(CommonMatchers.withImageAndComparableText(imageId, R.id.rlParentView, R.id.name, is(parcelId)))
            .check(matches(isDisplayed()));

希望有帮助