Android Espresso测试更高:view1高于view2

时间:2017-03-04 14:25:11

标签: android ui-testing

我根据用户操作使用动画移动视图( view1 view2 )。 在特定情况下,两个视图是重叠的。

我想确保 view1 高于 view2 。 问题是 view1 不在 view2 之上(它们是重叠的)所以我不能使用断言 isAbove

如何测试该场景?

1 个答案:

答案 0 :(得分:1)

如果有其他人需要,我找到了解决方案并将其发布在此处:

我创建了一个 CustomViewAssertions 类,并从 PositionAssertions 类中复制了相关部分:

relativePositionOf - 未更改

findView - 与内部类

完全不同

getTopViewGroup - 未更改

isRelativePosition - 更改比较逻辑

排名 - 新的枚举值

最终结果:

public class CustomViewAssertions {
    public static ViewAssertion isHigher(Matcher<View> matcher) {
        return relativePositionOf(matcher, Position.HIGHER);
    }

    public static ViewAssertion isHigherOrSame(Matcher<View> matcher) {
        return relativePositionOf(matcher, Position.HIGHER_OR_SAME);
    }

    private static ViewAssertion relativePositionOf(final Matcher<View> viewMatcher,
                                                    final Position position) {
        return new ViewAssertion(){
            @Override
            public void check(final View foundView, NoMatchingViewException noViewException) {
                StringDescription description = new StringDescription();
                if (noViewException != null) {
                    description.appendText(String.format(
                            "' check could not be performed because view '%s' was not found.\n",
                            noViewException.getViewMatcherDescription()));
                    throw noViewException;
                } else {
                    description.appendText("View:").appendText(HumanReadables.describe(foundView))
                               .appendText(" is not ")
                               .appendText(position.toString())
                               .appendText(" view ")
                               .appendText(viewMatcher.toString());
                    assertThat(description.toString(), isRelativePosition(foundView, findView(viewMatcher, getTopViewGroup(foundView)), position), is(true));
                }
            }
        };
    }

    private static View findView(Matcher<View> viewMatcher, View topViewGroup) {
        Iterable<View> views = breadthFirstViewTraversal(topViewGroup);
        LinkedList<View> matchedViews = new LinkedList<>();
        for (View view : views) {
            if (viewMatcher.matches(view)) {
                matchedViews.add(view);
            }
        }
        if (matchedViews.isEmpty()) {
            throw new NoMatchingViewException.Builder()
                    .withViewMatcher(viewMatcher)
                    .withRootView(topViewGroup)
                    .build();
        }
        if (matchedViews.size() == 1) {
            return matchedViews.get(0);
        }

        // Ambiguous!
        throw new AmbiguousViewMatcherException.Builder()
                .withRootView(topViewGroup)
                .withViewMatcher(viewMatcher)
                .withView1(matchedViews.remove(0))
                .withView2(matchedViews.remove(0))
                .withOtherAmbiguousViews(matchedViews.toArray(new View[matchedViews.size()]))
                .build();
    }

    private static ViewGroup getTopViewGroup(View view) {
        ViewParent currentParent = view.getParent();
        ViewGroup topView = null;
        while (currentParent != null) {
            if (currentParent instanceof ViewGroup) {
                topView = (ViewGroup) currentParent;
            }
            currentParent = currentParent.getParent();
        }
        return topView;
    }

    private static boolean isRelativePosition(View view1, View view2, Position position) {
        int[] location1 = new int[2];
        int[] location2 = new int[2];
        view1.getLocationOnScreen(location1);
        view2.getLocationOnScreen(location2);

        switch (position) {
            case HIGHER:
                return location1[1] < location2[1];
            case HIGHER_OR_SAME:
                return location1[1] <= location2[1];
            default:
                return false;
        }
    }

    private enum Position {
        HIGHER("higher"),
        HIGHER_OR_SAME("higher or same");

        private final String positionValue;

        Position(String value) {
            positionValue = value;
        }

        @Override
        public String toString() {
            return positionValue;
        }
    }
}