总目录:Espresso从开始到…
只要使用了Espresso,那么你一定不会对withId(R.id.xxx)和withText(R.string.xxx)这些ViewMatchers感到陌生。实际上无论是ViewMatchers、RootMatchers亦或者是Matchers,这些本质上都是Matcher。只是为了方便不同的使用环境进行了封装,本文将对Matcher以及这些封装后的工具进行分析。
Matcher
所有的matcher都实现了接口Matcher
public interface Matcher<T> extends SelfDescribing {
//遍历当前视图中的 view ,匹配则返回true,失败返回false
boolean matches(Object item);
//生成本次匹配操作的描述信息
void describeMismatch(Object item, Description mismatchDescription);
}
其中matches()是匹配的重点所在,在这里执行匹配的操作。
但是在使用过程中,我们并没有直接实现Matcher,而是实现其子类BaseMatcher所派生的封装类:TypeSafeMatcher和BoundedMatcher
1.TypeSafeMatcher
TypeSafeMatcher封装后的最大的区别是,增加了 isInstance()检查当前参加匹配的目标是否符合条件。我们看一下源码,为了便于区别和阅读,只筛选出来一部分代码:
public abstract class TypeSafeMatcher<T> extends BaseMatcher<T> {
final private Class<?> expectedType;
protected TypeSafeMatcher(Class<?> expectedType) {
this.expectedType = expectedType;
}
protected abstract boolean matchesSafely(T item);
public final boolean matches(Object item) {
return item != null
&& expectedType.isInstance(item)
&& matchesSafely((T) item);
}
final public void describeMismatch(Object item, Description description) {
......
}
}
这里我们可以清楚的看出和原始的BaseMatcher最大的区别是存储了一个expectedType,在matchesSafely()判断前会增加一个判断,当前 item是否是expectedType的实例或者子类。这样可以防止出现不同类型的恰好匹配的情况,相对于BaseMatcher是更加安全的。
我们看一个具体使用的栗子:
public static Matcher<View> withId(final int id) {
return new TypeSafeMatcher<View>() {
......
@Override
public void describeTo(Description description) {
......
}
@Override
public boolean matchesSafely(View view) {
......
return id == view.getId();
}
};
}
这是我们常用的onView(withId(R.id.xxx)),看过前一篇文章我们应该知道onView()这里需要的参数为Matcher,所以我们一般使用时,会采用上面的方

本文详细探讨了Espresso中的Matcher,包括TypeSafeMatcher和BoundedMatcher,它们为UI测试提供安全的匹配操作。TypeSafeMatcher增加了类型检查,确保匹配目标符合预期类型,而BoundedMatcher进一步强化了安全性。此外,还介绍了ViewMatchers、RootMatchers和Matchers的常用静态函数,帮助提高UI测试的效率。
最低0.47元/天 解锁文章
1090

被折叠的 条评论
为什么被折叠?



