(注意:本文基于UI Automator测试框架版本为2.2.0)
UI Automator测试框架中,等待功能需要指定对应的条件对象,今天学习作者对于条件对象的设计,该条件对象不是表示查找控件的条件:如UiSelector、BySelector,而是表示插桩测试能否继续运行的条件,如Condition、EventCondition、SerachCondition、UiObject2Condition
父类Condition
abstract class Condition<T, R> {
/**
* Applies the given arguments against this condition. Returns a non-null, non-false result if
* the condition is satisfied.
*/
abstract R apply(T args);
}
Condion类位于androidx.test.uiautomator包中,Condition为一个范型抽象类,表示需要满足的条件,它的子类将作为一个一个的条件对象而存在
apply(T args):抽象方法,子类会实现具体的判断条件,如果条件满足,那么此方法应该返回非空、非假的一个结果
子类SearchCondition
public abstract class SearchCondition<R> extends Condition<Searchable, R> {
}
子类SearchCondition类位于androidx.test.uiautomator包中,SearchCondition也是一个范型抽象类,继承了Condition,与控件的查找相关。它更进一步的表示一个具体的条件,表示一个查找UI元素的条件,并已经指定一个范型参数为Searchable,没有定义任何的方法!SearchCondition是通过搜索UI元素来满足的条件,后续的查找工作如果不满足此条件,将会一直处于查找的工作状态中
子类EventCondition
public abstract class EventCondition<R> extends Condition<AccessibilityEvent, Boolean> {
abstract Boolean apply(AccessibilityEvent event);
abstract R getResult();
}
子类EventCondition类位于androidx.test.uiautomator包中,EventConditon表示一个事件条件对象,与控件的事件相关。它依赖于已经发生的一个事件或一系列事件的条件!它在Condition的基础之上,又新增了两个抽象方法,重载的apply()对于AccessibilityEvent进行了判断,getResult()则用于获取条件的结果。
子类UiObject2Condition
public abstract class UiObject2Condition<R> extends Condition<UiObject2, R> {
}
子类UiObject2Condition类位于androidx.test.uiautomator包中,它在Condition的基础上,什么也没有做,不过指定好了一个参数类型为UiObject2,它与基于UiObject2作为结点的查找相关
三个子类都是抽象类,让我们看看具体的实现类
Until类位于androidx.test.uiautomator包中,提供的静态工厂方法,都是返回SearchCondition或者EventCondition或者UiObject2Condition,而且都是匿名内部类的形式哦!接下来我们进去Until类去看看有哪些方法!
Until类中返回SearchCondtion对象的静态工厂方法
共计4个
findObject():表示查找某个控件作为一个条件,满足条件后,将会返回一个UiObject2对象,否则返回null
findObjects():表示查找某一组控件作为一个条件,满足条件后,将会返回一个List对象,否则返回null
gone():表示没有找到控件作为一个条件,将会返回一个boolean值,true表示控件确实不存在,false表示控件存在
hasObject():表示是否包含某个控件作为一个条件,将会返回一个boolean值,true表示View树包含某个控件,false表示View树不包含某个控件
Until类中返回EventCondition对象的静态工厂方法
newWindow():表示新窗口作为一个条件,返回值是boolean值,true表示条件满足,为新窗口,false表示不是新窗口
scrollFinished():表示滑动完成事件作为一个条件,返回值为boolean值,true表示条件满足,表示滑动已经完成,false表示滑动没有完成
Until类中返回UiObject2Condition对象的静态工厂方法
关于返回UiObject2Condition对象的静态工厂方法如此众多,因为控件的状态有很多,具体我就不写了,看下API文档即可!
谁使用EventCondition对象?
1、GestureController类,位于androidx.test.uiautomator包中,performGestureAndWait()方法使用了EventCondition对象作为条件
public <R> R performGestureAndWait(EventCondition<R> condition, long timeout,
PointerGesture ... gestures) {
return getDevice().performActionAndWait(new GestureRunnable(gestures), condition, timeout);
}
2、UiDevice类,位于androidx.test.uiautomator包中,performActionAndWait()方法使用了EventCondition对象
public <R> R performActionAndWait(Runnable action, EventCondition<R> condition, long timeout) {
AccessibilityEvent event = null;
try {
event = getUiAutomation().executeAndWaitForEvent(
action, new EventForwardingFilter(condition), timeout);
} catch (TimeoutException e) {
// Ignore
}
if (event != null) {
event.recycle();
}
return condition.getResult();
}
3、EventForwardingFilter对象持有一个EventCondition对象,EventForwardingFilter类位于UiDevice类的内部,作为静态内部类存在
private static class EventForwardingFilter implements AccessibilityEventFilter {
private EventCondition<?> mCondition;
public EventForwardingFilter(EventCondition<?> condition) {
mCondition = condition;
}
@Override
public boolean accept(AccessibilityEvent event) {
// Guard against nulls
return Boolean.TRUE.equals(mCondition.apply(event));
}
}
4、最后当然是Until类,根据EventCondition,使用匿名内部类形式返回EventCondition对象,这里代码就不再贴了
谁使用SearchCondition对象?
1、UiDevice的wait()方法
public <R> R wait(SearchCondition<R> condition, long timeout) {
return mWaitMixin.wait(condition, timeout);
}
2、UiObject2的wait()方法
public <R> R wait(SearchCondition<R> condition, long timeout) {
return mWaitMixin.wait(condition, timeout);
}
3、Until类中的静态工厂方法,上文已描述就不说了
谁使用UiObject2Condition对象
1、UiObject2的wait()方法(重载)
public <R> R wait(UiObject2Condition<R> condition, long timeout) {
return mWaitMixin.wait(condition, timeout);
}
2、Until类中的静态工厂方法,继承了UiObject2Condition,上文已描述就不说了……
谁使用Condition对象
1、EventCondition、UiObject2Condition、SearchCondition都继承了Condition
2、WaitMixin类,位于androidx.test.uiautomator包中,其中两个重载的wait()方法都使用了Condition对象
总结
UiDevice与UiObject2的wait()方法,内部使用的是WaitMixin的wait()方法,这个时候EventCondition、UiObject2Condition均可以传入到WaitMixin类的wait方法中,因为他们都继承了Condition类。Condition作为基类,定义了基本的条件,每个子类根据不同的用途去扩展,最终回归本质的仍是一个条件!