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开始测试了!");
}
 
}

[uiautomator篇]uiwatcher 的使用场景的更多相关文章

  1. [uiautomator篇] UiWatcher的使用

    //package com.softwinner.pad.mark3d; package com.softwinner.performance.benchmark.mark3d; import and ...

  2. [uiautomator篇][1] 官网译文

    http://www.jianshu.com/p/7718860ec657 2016.07.25 20:59 字数 3675 Android UIAutomator浅谈 --------------- ...

  3. [uiautomator篇] 基类

      package com.softwinner.performance.benchmark; /** * UiAssistant public class * @author liuzhipeng ...

  4. spark第一篇--简介,应用场景和基本原理

    摘要: spark的优势:(1)图计算,迭代计算(2)交互式查询计算 spark特点:(1)分布式并行计算框架(2)内存计算,不仅数据加载到内存,中间结果也存储内存 为了满足挖掘分析与交互式实时查询的 ...

  5. 服务端指南 数据存储篇 | 聊聊 Redis 使用场景(转)

    作者:梁桂钊 本文,是升级版,补充部分实战案例.梳理几个场景下利用 Redis 的特性可以大大提高效率. 随着数据量的增长,MySQL 已经满足不了大型互联网类应用的需求.因此,Redis 基于内存存 ...

  6. [uiautomator篇][exist 存在,但click错误]

    uiautomator定位页面元素是,定位存在的;但是click的时候,发现点的位置不对,(不知道是android系统的问题还是uiautomator的问题,初步怀疑是系统的问题)

  7. [uiautomator篇] 使用uiautomator需要导入uiautomator库

    1 修改依赖文件:build/gradle( 是在app目录下)而不是和app同级目录的build/gradle androidTestCompile 'com.android.support.tes ...

  8. [Uiautomator篇][2] UiDeviceAPI介绍

    1 https://developer.android.com/training/testing/ui-testing/uiautomator-testing.html  http://www.cnb ...

  9. [UiAutomator篇][3] 打开音乐应用的测试脚本

    package qq.test; import android.content.Context; import android.content.Intent; import android.suppo ...

随机推荐

  1. WdatePicker时间插件 有百度云下载 jsp界面选择时间的简单方法

      链接:https://pan.baidu.com/s/1XCod602gCMv-qMQ4fMOLbg 提取码:ok8i 复制这段内容后打开百度网盘手机App,操作更方便哦 把东西复制到项目.导入j ...

  2. log explorer使用的几个问题[转载]

    1)对数据库做了完全 差异 和日志备份备份时选用了删除事务日志中不活动的条目再用Log explorer打试图看日志时提示No log recorders found that match the f ...

  3. 洛谷 P2922 [USACO08DEC]秘密消息Secret Message

    题目描述 Bessie is leading the cows in an attempt to escape! To do this, the cows are sending secret bin ...

  4. 宠溺旧习,win10清单-配置与软件

    从win98到win7塑就的旧“习 不是一两天能随了win10的任性 输入法反win X的头疼与苦恼 开机总要输密码的麻烦与滋扰 还有着一些莫名其妙的问题, 在过往与如今的交织间错乱. -序 好吧,其 ...

  5. Luogu P5327 [ZJOI2019]语言

    ZJOI2019Day2的温暖题,然后考场上只会大常数的\(O(n\log^3 n)\),就懒得写拿了60pts走人 首先我们简化题意,容易发现每个点能到达的点形成了一个联通块,我们只需要统计出这个联 ...

  6. JavaScript异步仿同步(控制流)的实现

    在前端开发中尤其是在nodejs开发中经常会遇到这样的场景(以ajax为例):有3个(或者更多个)Ajax请求,并且第2个请求依赖于第1个,第3个请求依赖于第2个,那我们可能就会在发第一个Ajax后回 ...

  7. C++11:移动构造函数的测试

    C++11:移动构造函数的测试 代码如下: #include <iostream> #include <stddef.h> #include <Windows.h> ...

  8. valgrind测试程序内存泄漏问题

    1.用wincap将valgrind放入系统任意路径下,解压 2.  登录主机后台在需要测试程序的路径下运行此行命令: /opt/valgrind/bin/valgrind ./itb(例) 3. 跑 ...

  9. CPP-网络/通信:POST

    BOOL PostSubmit(CString strUrl,const CString&strPara, CString&strContent){ BOOL bRet=FALSE; ...

  10. Hibernate查询语句HQL8大特点

    Hibernate拥有一种功能非常强大的查询语言,这种语言被有意得与SQL非常相似,便于开发人员掌握.但不要被HQL的语法表面所迷惑,HQL完全是面向对象的,可以用来过程多态.继承.关联等关系. 1. ...