http://www.yangyanxing.com/article/use-watcher-in-uiautomator.html

 

今天在uiautomator中实践了watcher的用法,这个也是之前在python中使用uiautomator中比较喜欢的功能,它可以提前定义一些条件,当满足一些条件时,进行一些操作,这个常用于处理测试过程中某些意料之外的或者不知道什么时候弹出来的框而阻碍测试的正常进行。
之前在写自动化用例的时候,遇到过小米手机在安装app的时候,会弹一个框来让用户点击安装,还有弹出一个升级检测的框点击“取消”按钮,或者遇到退出的时候点击确定,当然这些完全可以在用例里写逻辑来处理,而且有些还是程序本身要测试的检测点,当然这些对于大多数测试来说没有太大的意义,所以可以将其放入一个watcher里来让uiautomator来帮你进行相应的点击处理。

查看官方文档, UiWatcher是由UiDevice来registerWatcher (String name, UiWatcher watcher),name为一个名字,这个名字相当于一个key,可以在之后的查看该watcher是否被检测到了使用和remove的时候使用

初始化UiWatcher时要重写一个checkForCondition()这个抽象方法,这个方法主要就是写一些判断哪些UiSelector是否出现了,出现了怎么处理,我重新封装了一个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public void initwatch(final String name,final UiSelector checkSelecto,final UiSelector opSelector){
//将name添加到watcherNames的list中,为了tearDown方法中remove掉用
watcherNames.add(name);
final UiObject check = new UiObject(checkSelecto);
final UiObject op = new UiObject(opSelector);
mDevice.registerWatcher(name, new UiWatcher() {
//这里重写checkForCondition方法
public boolean checkForCondition() {
try {
if (check.exists()) {
op.click();
Thread.sleep(1000);
return true;
}
else{
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
 
return false;
}
});
}

checkForConditon方法的返回值是boolean值,当返回true的时候,则uidevice.hasWatcherTriggered(name) 则返回true,checkForConditon这里不用写循环,uiautomator会在测试过程中一直在循环的调用。

以下是全部代码
TestUtil.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.yangyanxing.test;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
 
import com.android.uiautomator.core.UiDevice;
import com.android.uiautomator.core.UiObject;
import com.android.uiautomator.core.UiSelector;
import com.android.uiautomator.core.UiWatcher;
 
public class TestUtil {
public ArrayList<String> watcherNames = new ArrayList<String>();
public UiDevice mDevice = UiDevice.getInstance();
 
public static String doCmdshell(String commond){
String s = null;
try
{
Process p = Runtime.getRuntime().exec(commond);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
 
String result = "";
while ((s = stdInput.readLine()) != null)
{
result = result + s + "\n";
}
while ((s = stdError.readLine()) != null)
{
System.out.println(s);
}
return result;
}
catch (Exception e)
{
return "Exception occurred";
}
}
//init watcher
 
 
public void initwatch(final String name,final UiSelector checkSelecto,final UiSelector opSelector){
//将name添加到watcherNames的list中,为了tearDown方法中remove掉用
watcherNames.add(name);
final UiObject check = new UiObject(checkSelecto);
final UiObject op = new UiObject(opSelector);
mDevice.registerWatcher(name, new UiWatcher() {
//这里重写checkForCondition方法
public boolean checkForCondition() {
try {
if (check.exists()) {
op.click();
Thread.sleep(1000);
return true;
}
else{
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
 
return false;
}
});
}
 
 
public static Boolean waitForUiselectorAppears(UiSelector selector,int timeout)
{
UiObject uiObject = new UiObject(selector);
return uiObject.waitForExists(timeout*1000);
}
 
}

UitestRunner.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.yangyanxing.test;
 
import com.android.uiautomator.core.UiDevice;
import com.android.uiautomator.core.UiObject;
import com.android.uiautomator.core.UiObjectNotFoundException;
import com.android.uiautomator.core.UiSelector;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;
import static com.yangyanxing.test.TestUtil.doCmdshell;
 
 
public class UitestRunner extends UiAutomatorTestCase {
//初始化一个UiDevice
private UiDevice mDevice = UiDevice.getInstance();
private TestUtil tUtil = new TestUtil();
 
public UitestRunner(){
super();
}
//写setUp()方法
public void setUp() throws Exception{
super.setUp();
//每次测试的时候都需要启动急救箱,所以将这个方法放到setUp里
doCmdshell("am start com.qihoo.mkiller/com.qihoo.mkiller.ui.index.AppEnterActivity");
System.out.println("开始测试啦。。。");
//注册一些watcher
tUtil.initwatch("ignorSafe", new UiSelector().textContains("安全上网").className("android.widget.TextView"),
new UiSelector().text("取消"));
tUtil.initwatch("agree", new UiSelector().text("同意并使用"),
new UiSelector().text("同意并使用"));
tUtil.initwatch("Noupdate", new UiSelector().textContains("升级"),
new UiSelector().text("取消"));
mDevice.runWatchers();//将watchers运行起来
}
 
//写tearDown方法,将急救箱force-stop
public void tearDown() throws Exception{
super.tearDown();
doCmdshell("am force-stop com.qihoo.mkiller");
System.out.println("用例测试完了!");
for (String watcherName : tUtil.watcherNames) {
System.out.println(watcherName+"被remove了!");
mDevice.removeWatcher(watcherName);
}
}
 
//检测急救箱启动后是否有"开始扫描"按钮
 
public void test_startScanButton() throws UiObjectNotFoundException{
UiSelector scanButton = new UiSelector().className("android.widget.Button").text("开始扫描");
if(TestUtil.waitForUiselectorAppears(scanButton, 20)){
UiObject scanoObject = new UiObject(scanButton);
if (scanoObject.click()) {
System.out.println("开始扫描 按钮被点击了!");
}else{
System.out.println("开始扫描 按钮点击失败了");
}
}else {
System.out.println("急救箱启动失败");
}
 
UiSelector exitbutton = new UiSelector().className("android.widget.Button").text("退出");
 
assertEquals(Boolean.TRUE, TestUtil.waitForUiselectorAppears(exitbutton, 120));
}
 
public void test_print(){
System.out.println("用例2开始测试了!");
}
 
}

最新文章

  1. Linux命令集合
  2. Mac常用命令
  3. 用#define来实现多份近似代码 - map,set中的应用
  4. Nginx-Lua重定向系列
  5. jq 选项卡
  6. Umbraco中Document Type取名限制
  7. 如何计算IP地址及CIDR,子网掩码计算
  8. (二)Angularjs - 入门(2)
  9. [LeetCode]题解(python):011-Container With Most Water
  10. 带你深入理解STL之RBTree
  11. 《java入门第一季》之泛型方法和泛型接口
  12. html2canvas 识别 svg 解决方案
  13. leetcode53
  14. 手把手教你实现Confluence6.7.1安装与破解
  15. Python 函数的作用域
  16. nvidia-docker
  17. Codeforces 140D - New Year Contest
  18. Requests接口测试-对cookies的操作处理(一)
  19. HTML常用标签及其属性
  20. 《java并发编程实战》读书笔记7--线程池的使用

热门文章

  1. 一本通 1434:【例题2】Best Cow Fences
  2. codeforces736D. Permutations(线性代数)
  3. 【学习笔记】八:浏览器对象模型BOM
  4. 在PaaS上开发Web、移动应用(2)
  5. 基于H5+ API手机相册图片压缩上传
  6. vue+element ui项目总结点(四)零散细节概念巩固如vue父组件调用子组件的方法、拷贝数据、数组置空问题 等
  7. Java poi 的使用
  8. python基础一 day13 复习
  9. js 监听页面url锚点变化 window.onpopstate
  10. Catalan 数