UiAutomator 与 Shell 结合的力量
自学UiAutomator并使用已快一年了,也独自完成了项目中的800条自动化测试用例的编写,其中坑坑洼洼亦不知多少,更不消说UiAutomator本身就有Bug了.现如今也来说说一点小想法.这里我主要想讲一下,最近在编
写自动化测试PC端工具时,所想到的一些点子.
我的想法就是通过UiAutomator本身的dump命令,来抓取手机当前页面的xml档,这个xml档里面有存储手机当
前页面的属性及坐标等.接着通过shell脚本命令来解析或过滤出我们想要点击的属性的坐标值来,最后通过sen
devent的方式来实现:点击/长按/滑动(Swipe)/双击/拖拽(Drag)/多点点击等操作.
阅读前提:
读者需要掌握uiautomator的基本用法
读者需要掌握shell脚本的基本用法,以及grep与sed的常用方法
首先,我们需要借助UiAutomator抓取手机当前页面的配置信息,我们在DOS命令行中,执行adb shell uiautom
ator dump时,会自动生成一份文件,并存储在手机的SD 卡根目录中,名为:window_dump.xml.读者可以
将它复制到电脑上来查看,其实这个文件和我们在电脑上借助Android SDK中,uiautomatorviewer.bat来察看
手机当前页面的属性等值的方法是一样的.
REM 这里是DOS命令行,REM为DOS命令行注释,请知悉
REM 这里使用的是小米手机,Android Version: 4.4.4
C:\Users\Administrator>adb shell uiautomator dump
UI hierchary dumped to: /storage/emulated/legacy/window_dump.xml
那抓出来的档案是可以在电脑上来查看的,形如:
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="com.miui.notes" c
ontent-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focus
ed="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="">
<!--这里提注释,内容太多,抱歉,不便全列,省略若干字哈 -->
</hierarchy>
接着,这里我们介绍如何借助强大的Shell脚本,来抓取/过滤出我们想要的东东,
getCoordinateByAttribution()
{
#这里我们定义了一个instance,它的灵感是来自UiAutomator中的同名操作.意思是在当前页面下,有n个一
模一样的属性,我们不好区分时,使用instance来指出我们需要点击的是第一个还是第n个属性.默认点击第
一个.
instance=""
instance=${instance:=$2}
instance=${instance:=1}
uiautomator dump
#这里借助了busybox工具,至于什么是busybox工具以及如何安装,此处暂不讲,读者可以先行百度,若有
困难,再说.
#这里借助grep命令,来过滤出我们需要点击的属性,个人认为此方法比UiAutomator这个工具本身要方便一
些.UiAutomator本身做了很多的区别,比如text,descrption,resourceId等等.
temp=`cat /mnt/sdcard/window_dump.xml|busybox sed 's/>/\n/g'|busybox grep "$1"|busybox sed -n {$2}p`
temp=`echo ${temp%]\"*}`
temp=`echo $temp|busybox awk '{print $NF}'`
#此处我们作一个判断,如果temp的值不等空串的话,我们认为找到了我们需要查找的属性,并作进一步的处理
if busybox test ! "$temp" == ""
then
temp=`echo ${temp/bounds=/}`
temp=`echo $temp| busybox sed 's/"//g'| busybox sed 's/\[//g'| busybox sed 's/\]/\n/g'`
p1=`echo $temp|busybox awk '{print $1}'`
p2=`echo $temp|busybox awk '{print $2}'`
#定义四个变量,用例存储找到的属性的四个坐标值
p1x=`echo ${p1%,*}`
p1y=`echo ${p1#*,}`
p2x=`echo ${p2%,*}`
p2y=`echo ${p2#*,}`
let centerX=$p1x/2+$p2x/2
let centerY=$p1y/2+$p2y/2
else
#这里是查找属性失败时的动作
echo `date +%m-%d-%H-%M-%S` getCoordinateByAttribution $1 failed >> /mnt/sdcard/log.txt
#screencap是android自带的可以抓图的命令,这里加上了时间而已
screencap -p /mnt/sdcard/"`date +%m-%d-%H-%M-%S`".png
fi
}
这个函数如何调用呢?容我举例说明,我们可在shell脚本中执行以下命令来调用它.
#这是一个查找点击text属性的例子,这里加上双引号是因为,即使字串中有空格时,也不会被当成两个参数
来处理
getCoordinateByAttribution "text" 1
#这是一个查找点击description属性的例子
getCoordinateByAttribution "description" 1
#这是一个查找点击resourceId属性的例子
getCoordinateByAttribution "resourceId" 1
#如果有三个一模一样的resourceId属性,而我们需要点击第三个属性的话
getCoordinateByAttribution "resourceId" 3
OK,既然已查找到属性,如何点击它呢?这里我们借用android自带的sendevent方法,当然你也可以使用inp
ut命令来点击,因为坐标值我们已经获取到了.
这里还是用小米2移动定制手机为例,
#这里定义了点击的shell函数
Tap()
{
sendevent /dev/input/event0 3 57 1
sendevent /dev/input/event0 3 53 $1
sendevent /dev/input/event0 3 54 $2
sendevent /dev/input/event0 1 330 1
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 3 53 $1
sendevent /dev/input/event0 3 54 $2
sendevent /dev/input/event0 0 0 0
}
#结合前面所述,我们只需点击对应坐标便可
Tap $centerX $centerY
:victory:
页:
[1]