espresso之Views获取

Espresso在处理多个匹配的View时会抛出Ambiguous异常,使得遍历操作变得困难。本文探讨如何在Android测试中,针对相同View类型进行循环操作,包括使用空的ViewAction收集匹配的View,并通过自定义ViewAction实现逐个点击。

espresso 目前尚不能处理多个View , 不论是 onData 还是其他 , 都只能操作唯一匹配的View . 如果多个view被匹配 , 将抛出 AmbiguousViewMatcherException 这个异常 , 那么我们想循环遍历操作一组同类的views时 将变得不太现实 .

举个例子有一波 Text 相同的View , 我想全部点击一遍 , 一个个的通过复杂定位去点击 , 显然不太现实 .

那么是自己动手实现的时候了 , 此文在此抛砖引玉了 , 若有更好的方法 , 烦请告知哈 . 之前翻看源码后 , 用反射将 ViewInteraction 对象的属性全拿出来重组 , 再通过 ViewHandlegetTargetViews() , 然而这种效率是很低的 .

Talk is cheep :

public class ViewsFinder {
    private List<View> views = new ArrayList<>();
    private boolean has_more_views;
    private final String TAG = this.getClass().getSimpleName();

    private Matcher<View> thisMatcher(Matcher<View> matcher){
        return new TypeSafeMatcher<View>() {
            @Override
            public void describeTo(Description description) {
                description.appendText("this is a view finder .");
            }

            @Override
            protected boolean matchesSafely(View view) {
                if(matcher.matches(view)){
                    views.add(view);
                    return true;
                }
                return false;
            }
        };
    }

    private void hasViews(Matcher<View> matcher){
        try {
            //下面的nothing() , 是一个空的 ViewAction
            onView(thisMatcher(matcher)).perform(nothing());
            has_more_views = true;
        } catch (AmbiguousViewMatcherException e) {
            has_more_views = true;
        } catch (Exception ne){
            Log.e(TAG, "hasViews: ", ne);
            has_more_views = false;
        }
    }

    public List<View> getViews(Matcher<View> matcher) {
        this.hasViews(matcher);
        if(has_more_views)
            return views;
        else {
            Log.w(TAG, "getViews: 没有匹配的view" );
            return null;
        }
    }
}

初步使用 :

ViewsFinder viewsFinder = new ViewsFinder();
        List<View> recycler = viewsFinder.getViews(withResourceName("recycler"));

在调用 getViews 方法时将会执行 nothing() 这个空的 ViewAction , 这样不会对元素进行具体的操作 , Matcher 总是在 perform 执行的时候才去取 View , 并一个个的进行匹配 . 这时 , 匹配到一个就views.add(view) 这样放进list中去了 .

Views 列表是有了 , 那么接下来的操作 就可以for 循环了 . 啥 ? 光个view 怎么用 ? 自定义个Matcher 就搞定了嘛 .

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值