UIWatcher,是UIAutomator的接口类,用于处理测试中出现的“意外打断”情况(若不对意外情况进行处理,将导致CASE Failed,影响测试结果)。例如电话打入,闹钟之类的界面插入。
该类只有一个函数需要实现。
public boolean checkForCondition();
该方法的返回值为布尔类型。若为true,则表示该Watcher符合条件,被触发。否则,表示不符合条件,未被触发。当然,返回结果由coder自己说了算。
那什么时候,触发UIWatcher呢?官方文档给出了说明。
仅在未找到以UISelector为查询条件的UI控件时,才由系统框架触发,按照UIWatcher的注册顺序,逐一执行。并根据checkForCondition方法的返回值,认定该UIWatcher是否被触发(是否符合触发条件)。
UIDevice共提供了6个相关方法,分别是
public void registerWatcher(String name, UiWatcher watcher)//用于注册
public boolean hasAnyWatcherTriggered() //判断是否有任何一个UIWatcher被触发
public boolean hasWatcherTriggered(String watcherName)//判断某个UIWatcher是否被触发
public void resetWatcherTriggers()//重置所有UIWatcher的Trigger标记
public void removeWatcher(String name) //移除UIWatcher
public void runWatchers()//手动运行所有UIWatcher
我们还是使用示例来演示方法的使用。
测试过程
1.创建三个UIWatcher
2.启动APP1(test),并连续点击check1
3.启动APP2(salaryshow),以打断连续的点击
LogAndFalseUIWatcher 类
public class LogAndFalseUIWatcher implements UiWatcher {
private final String TAG=getClass().getName();
@Override
public boolean checkForCondition() {
Log.i(TAG, "only return false");
return false;
}
}
LogAndTrueUIWatcher 类
public class LogAndTrueUIWatcher implements UiWatcher {
private final String TAG=getClass().getName();
@Override
public boolean checkForCondition() {
Log.i(TAG, "only return true");
return true;
}
}
PressBackUIWatcher 类
public class PressBackUIWatcher implements UiWatcher {
private final String TAG=getClass().getName();
private UiDevice mUIDevice;
public PressBackUIWatcher(UiDevice mUIDevice) {
this.mUIDevice = mUIDevice;
}
@Override
public boolean checkForCondition() {
Log.i(TAG, "press back");
mUIDevice.pressBack();
return false;
}
}
核心测试代码
public class UIWatcherTest extends UIDeviceTest {
private String mPackageName="com.breakloop.test";
private String mSalaryPackageName="com.breakloop.salaryshow";
private String mActivityName=".MainActivity";
private String text_check="check";
private long timeout=1000l;
@Before
public void start(){
Utils.startAPP(mDevice,mPackageName,mActivityName);
waitForAMoment();
}
private void waitForAMoment(){
mDevice.waitForWindowUpdate(mPackageName,timeout);
}
@After
public void end(){
Utils.closeAPP(mDevice,mPackageName);
waitForAMoment();
}
@Test
public void test1(){
boolean result=true;
UiObject ui=mDevice.findObject(new UiSelector().textStartsWith(text_check));
//注册UIWatcher
mDevice.registerWatcher("LogTrue",new LogAndTrueUIWatcher());
mDevice.registerWatcher("LogFalse",new LogAndFalseUIWatcher());
mDevice.registerWatcher("PressBack", new PressBackUIWatcher(mDevice));
Assert.assertFalse(mDevice.hasAnyWatcherTriggered());
//创建线程,在2秒后,启动其他APP,以打断现有操作
new Thread() {
@Override
public void run() {
Log.i(TAG, "run: start Salary APP");
try {
sleep(timeout*2);
} catch (InterruptedException e) {
Log.i(TAG, "Sleep failed");
e.printStackTrace();
}
Utils.startAPP(mDevice,mSalaryPackageName,mActivityName);
}
}.start();
//连续点击checkbox,之后将被打断
for(int loop=0;loop<10;loop++){
try {
Log.i(TAG, "Click Check "+loop);
ui.click();
waitForAMoment();
} catch (UiObjectNotFoundException e) {
e.printStackTrace();
result=false;
}
}
//查看UIWatcher触发情况,即各UIWatcher的checkForCondition方法返回值
Assert.assertTrue("LogTrue was Triggered", mDevice.hasWatcherTriggered("LogTrue"));
Assert.assertFalse("LogFalse was not Triggered",mDevice.hasWatcherTriggered("LogFalse"));
Assert.assertFalse("PressBack was not Triggered",mDevice.hasWatcherTriggered("PressBack"));
//重置各UIWatcher的触发标志位
mDevice.resetWatcherTriggers();
//再次查看UIWatcher触发情况
Assert.assertFalse("LogTrue was not Triggered",mDevice.hasWatcherTriggered("LogTrue"));
Assert.assertFalse("LogFalse was not Triggered",mDevice.hasWatcherTriggered("LogFalse"));
Assert.assertFalse("PressBack was not Triggered",mDevice.hasWatcherTriggered("PressBack"));
//移除LogTrue,然后运行剩余UIWatcher
mDevice.removeWatcher("LogTrue");
mDevice.runWatchers();
//移除LogFalse,然后运行剩余UIWatcher
mDevice.removeWatcher("LogFalse");
mDevice.runWatchers();
//移除PressBack,然后运行剩余UIWatcher
mDevice.removeWatcher("PressBack");
mDevice.runWatchers();
//查看打断后的CASE是否能够PASS
assertTrue(result);
}
}
执行结果如下
11-29 19:31:25.404 I/TestRunner: started: test1(com.breakloop.u2demo.uidevice.UIWatcherTest)
11-29 19:31:28.283 I/com.breakloop.u2demo.uidevice.UIWatcherTest: Click Check 0
11-29 19:31:28.284 I/com.breakloop.u2demo.uidevice.UIWatcherTest: run: start Salary APP
11-29 19:31:30.287 I/com.breakloop.u2demo.uidevice.UIWatcherTest: Click Check 1
11-29 19:31:32.312 I/com.breakloop.u2demo.uidevice.UIWatcherTest: Click Check 2
11-29 19:31:32.327 I/com.breakloop.u2demo.uidevice.uiwatcher.LogAndTrueUIWatcher: only return true
11-29 19:31:32.327 I/com.breakloop.u2demo.uidevice.uiwatcher.LogAndFalseUIWatcher: only return false
11-29 19:31:32.328 I/com.breakloop.u2demo.uidevice.uiwatcher.PressBackUIWatcher: press back
11-29 19:31:36.302 I/com.breakloop.u2demo.uidevice.UIWatcherTest: Click Check 3
11-29 19:31:38.305 I/com.breakloop.u2demo.uidevice.UIWatcherTest: Click Check 4
11-29 19:31:40.316 I/com.breakloop.u2demo.uidevice.UIWatcherTest: Click Check 5
11-29 19:31:42.325 I/com.breakloop.u2demo.uidevice.UIWatcherTest: Click Check 6
11-29 19:31:44.333 I/com.breakloop.u2demo.uidevice.UIWatcherTest: Click Check 7
11-29 19:31:46.337 I/com.breakloop.u2demo.uidevice.UIWatcherTest: Click Check 8
11-29 19:31:48.351 I/com.breakloop.u2demo.uidevice.UIWatcherTest: Click Check 9
11-29 19:31:50.362 I/com.breakloop.u2demo.uidevice.uiwatcher.LogAndFalseUIWatcher: only return false
11-29 19:31:50.362 I/com.breakloop.u2demo.uidevice.uiwatcher.PressBackUIWatcher: press back
11-29 19:31:50.436 I/com.breakloop.u2demo.uidevice.uiwatcher.PressBackUIWatcher: press back
11-29 19:31:56.078 I/TestRunner: finished: test1(com.breakloop.u2demo.uidevice.UIWatcherTest)
参考博文
https://testerhome.com/topics/465
http://blog.csdn.net/itfootball/article/details/42464875
http://blog.chengyunfeng.com/?p=505