espresso之自由swipe

本文探讨了在使用Espresso进行Android UI测试时遇到的滑动限制问题,尤其是在需要在浮动View上滑动的情景。通过创建一个自定义ViewAction,允许以坐标点为基准进行滑动操作,解决了在RootWindow上无法操作的问题。示例代码展示了如何使用这个自定义方法,以更优雅的方式实现自由滑动。

很多时候espresso不能自由的滑动 , 它必须在指定的View上进行 ( 当然 , view不可见的时候是不能滑动的 ) . 然而我们就是希望在屏幕上滑动一下来使某个view可见 , 一般情况很简单嘛 :

onView(isRoot()).perform(swipeLeft());
onView(isRoot()).perform(swipeDown());

这样真的就解决了吗 , 当然 . 这样可以解决大部分的问题 , 但如果说是在浮动出来的View上滑动呢 ? 比如 :
第三方日历控件

这时是无法在RootWindow上操作的了.
算了, 我们自己来吧 . 自由 ! 自由 !
自定义一个可以通过坐标点来滑动的 ViewAction:

public static final class SwipeAs implements ViewAction{
        /** Maximum number of times to attempt sending a swipe action. */
        private static final int MAX_TRIES = 3;

        private final Swiper swiper;
        private final float[] startCoordinates;   //开始坐标
        private final float[] endCoordinates;     //结束坐标
        private final float[] precision ;         //这个是精度

        public SwipeAs(Swiper swiper, float[] startCoordinates, float[] endCoordinates, float[] precision) {
            this.swiper = swiper;
            this.startCoordinates = startCoordinates;
            this.endCoordinates = endCoordinates;
            this.precision = precision;
        }

        @Override
        public Matcher<View> getConstraints() {
            return withAny();  //这个是啥? 当然是自定义的Matcher. 当心,它很关键 ,其意思是匹配所有 .(实现方式很简单,实现一个空的TypeSafeMatcher , 直接return true; 即可.) 如若不会, 请参见余前面的关于自定义Matcher的博客.
        }

        @Override
        public String getDescription() {
            return "swipe .";
        }

        @Override
        public void perform(UiController uiController, View view) {
            Swiper.Status status = Swiper.Status.FAILURE;

            for (int tries = 0; tries < MAX_TRIES && status != Swiper.Status.SUCCESS; tries++) {
                try {
                    Log.i(TAG, "SwipeAs perform .swipe as : "+ Arrays.toString(startCoordinates)
                            + " -> "+ Arrays.toString(endCoordinates) +
                            " ; precision : "+ Arrays.toString(precision));

                    status = swiper.sendSwipe(uiController, startCoordinates, endCoordinates, precision);
                } catch (RuntimeException re) {
                    throw new PerformException.Builder()
                            .withActionDescription(this.getDescription())
                            .withViewDescription(HumanReadables.describe(view))
                            .withCause(re)
                            .build();
                }

                int duration = ViewConfiguration.getPressedStateDuration();
                // ensures that all work enqueued to process the swipe has been run.
                if (duration > 0) {
                    uiController.loopMainThreadForAtLeast(duration);
                }
            }

            if (status == Swiper.Status.FAILURE) {
                throw new PerformException.Builder()
                        .withActionDescription(getDescription())
                        .withViewDescription(HumanReadables.describe(view))
                        .withCause(new RuntimeException(String.format(
                                "Couldn't swipe from: %s,%s to: %s,%s precision: %s, %s . Swiper: %s "
                                        + "start coordinate provider: %s . Tried %s times",
                                startCoordinates[0],
                                startCoordinates[1],
                                endCoordinates[0],
                                endCoordinates[1],
                                precision[0],
                                precision[1],
                                swiper,
                                Arrays.toString(startCoordinates),
                                MAX_TRIES)))
                        .build();
            }
        }
    }

当然某些部分还是直接从Google API中摘出来的 , 如异常部分.
初步使用:

onView(isRoot()).perform(
                new CustomViewAction.SwipeAs(Swipe.FAST ,new float[]{213.0f ,1578.356f} 
                        ,new float[]{213.0f ,1517.0f} , Press.FINGER.describePrecision())
        );

试试看, 还不错吧 . 这乱糟糟的有什么用 , 不好看也不好写 . 嘿 , 这之后的封装工作当然就是课后作业了哈.
经过层层封装后 当然也可以这么优雅 :

onView(isRoot()).perform(swipeUpAs());

只不过这中间的封装一篇博文是说不完的 ( 也不过些基础知识 ).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值