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. Asp.net开发必备51种代码

    1.//弹出对话框.点击转向指定页面 Response.Write("<script>window.alert('该会员没有提交申请,请重新提交!')</script> ...

  2. React 实践记录 01 组件开发入门

    Introduction 本文组成: Ryan Clark文章Getting started with React的翻译. 博主的实践心得. React由Facebook的程序员创建,是一个非常强大的 ...

  3. hybrid app开发中:苹果移动设备实用Meta标签

    hybrid app开发中:苹果移动设备实用Meta标签 “apple-mobile-web-app-status-bar-style”作用是控制状态栏显示样式 具体效果如下: status-bar- ...

  4. Azure Powershell 获取可用镜像 PublisherName,Offer,Skus,Version

    #登录 $username="{登录名}" #定义一个用户账号的变量,可以输入需要登录的订阅账号名称 $password=ConvertTo-SecureString -Strin ...

  5. git处理时的问题

    1. 在node.js开发的时候常常会遇到从别人的远程仓库中clone时出现文件名过长的错误, 或则是在本地npm下载之后的文件进行上传到自己的远程仓库的时候会出现 File too long的情况, ...

  6. COGS 2566. [51nod 1129] 字符串最大值

    ★★★   输入文件:string_maxval.in   输出文件:string_maxval.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] 一个字符串的前缀是指包 ...

  7. ubuntu 16.0安装 hadoop2.8.3

    环境:ubuntu 16.0 需要软件:jdk ssh https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/ 2.8.3 安装 jdk并 ...

  8. Python 元组、字典、集合操作总结

    元组 a=('a',) a=('a','b') 特点 有序 不可变,不可以修改元组的值,无法为元组增加或者删除元素 元组的创建 a=('a',) a=('a','b') tuple('abcd') 转 ...

  9. eltwise层

    http://blog.csdn.net/u013989576/article/details/73294131 layer { name: "fuse" type: " ...

  10. 毛毛虫组【Beta】Scrum Meeting 3

    第三天 日期:2019/6/25 前言 第三次会议: 时间:6月25日 地点:教10-A511 内容:此次会议主要是对项目验收做准备工作. 1.1 今日完成任务情况以及遇到的问题. 今日完成任务情况: ...