一 使用目的
该工具主要是基于appium,可以面向Android和Ios移动App,或H5或微信等应用的,基于元素识别的UI自动化遍历测试.
该工具特点:
1.支持最新的appium 1.8.1 (AppCrawler支持1.7.0)
2.安卓方向支持monkey配置遍历.
3.结果报告上看,支持Crash信息搜集.会对操作过程录制视频.会对操作过程每动作截图.
其他优质特性详见github主页说明
二 资源索引
官方资源
UICrawler Github
UICrawler 配置文件说明
UICrawler 环境配置说明
博客相关
基于 Appium 的 App UI 遍历工具 (支持操作步骤回放)
网盘下载链接
三 环境准备
以安卓方向取重点:
Oracle Java部署
下载地址 http://www.oracle.com/technetwork/java/javase/downloads/index.html
找到合适的java版本下载,我选择的是jdk-8u91-windows-x64.exe。按步骤安装即可。安装路径一般默认。
配置java 环境变量:
JAVA_HOME 变量值为JDK的安装目录,笔者为C:\Program Files\Java\jdk1.8.0_91
PATH PATH变量值后追加 ;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
CLASSPATH 变量值为 ;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
检查是否安装成功
C:\Users\cmd>java -version
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b15, mixed mode)
Android sdk部署
下载地址 android-sdk_r24.4.1-windows 处下载 android-sdk_r24.4.1-windows.zip
将android-sdk-windows解压到你需要的目录下,笔者是D:\Android\android-sdk-windows
配置android-sdk环境变量:
ANDROID_HOME 变量值为android-sdk的解压目录,笔者为D:\Android\android-sdk-windows
PATH PATH变量值的最后追加 ;%ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools;%ANDROID_HOME%\build-tools;
接下来你便可以用D:\Android\android-sdk-windows 下的SDK Manager.exe下载配置SDK 或AVD Manager.exe 配置 AVD模拟器了。
如果你需要测试android应用的话,请先安装配置好某一版本的SDK及其相关工具。
如下图,SDK manager必要配置:
Tools->Options设置:
[图片上传失败...(image-3294ca-1528341709166)]
其它要下载的:
我目前的配置是
[图片上传失败...(image-9ac803-1528341709166)]
此处的按需选择与AVD模拟器配套使用的:
[图片上传失败...(image-8bf55c-1528341709166)]
[图片上传失败...(image-585a9a-1528341709166)]
#检查下最终的adb版本
C:\Users\cmd>adb version
Android Debug Bridge version 1.0.39
Version 0.0.1-4500957
Installed as D:\Android\android-sdk-windows\platform-tools\adb.exe
appium部署
可以用两种方式:
一种就是直接用desktop版本, [appium-desktop](https://github.com/appium/appium-desktop/releases/tag/v1.6.1)
一种就是nodejs部署参考,[教您完美 win10 安装 Appium1.7.2 支持 win 客户端自动化](https://testerhome.com/topics/12988)
(建议使用nodejs部署方式,该文可以完美安装当然你不做winuiauto的话可以忽略文中提到的那些winuiauto相关的报错)
手机真机相关设置
真机小米Mix2
需要开启真机开发者选项->USB调试,模式和其他相关,主要是调试这一栏要打开的有
哦,还有就是接上手机的时候,小米Mix会提示选择"USB用途" (有 1 仅限充电 2 传输文件MTP 3传输照片 PTP) 你需要选择 传输文件MTP 该项.否则 adb devices -l会报一个类似权限未获取到的提示.
部署UICrawler相关
目前尚未完全开源,可以直接去网盘下载UICrawler-2.0.jar和config.yml 到本地磁盘即可.
我是先 git clone https://github.com/lgxqf/UICrawler.git 然后将上述下载的文件放入.
先通过自带的-h 命令检查UICrawler-2.0 是否正常
D:\UICrawler>java -jar UICrawler-2.0.jar -h
15:32:08.083 [main] INFO Crawler - -h Print this usage information
-a Android package's main activity
-b iOS bundle id
-c Maximum click count
-f Yaml config file
-m run monkey
-p Android package name
-t Appium port
-u Device serial
-w wda port for ios
四 配置修改
config.yml 用文本编辑器打开,个人推荐win环境用Notepad++,ubuntu环境用Notepadqq.
并且打开"显示所有字符",以便查看是否符合yml文件编辑格式规范,空格 回车换行符什么的.
配置参考:
YAML 语言格式
XPath 教程
附上最终修改后配置:
GENERAL:
#截屏数量
SCREENSHOT_COUNT: 500
#Crash时截图显示步骤数量
CRASH_PIC_COUNT: 5
#遍历深度
MAX_DEPTH: 2000
#点击次数
MAX_CLICK_COUNT: 100000
#TIME
DEFAULT_WAIT_SEC: 10
#查找元素的间隔时间
DEFAULT_POLLING_INTERVAL_SEC: 5
DEFAULT_VALUE:
#Appium server IP, 0.0.0.0代表Server在本地
APPIUM_SERVER_IP: 0.0.0.0
#Appium端口
PORT: 4723
#IOS 才会用到WDA_PORT
IOS_WDA_PORT: 8001
#是否忽略Crash,设为true时,crash后会重启app然后继续遍历
IGNORE_CRASH: true
ENABLE_VERTICAL_SWIPE: true
#设置事件百分比 各事件百分比之和为100
MONKEY:
#运行时间,以分钟计
MONKEY_RUNNING_TIME: 180
#以下各项值总和需为100
#滑动事件百分比
SWIPE_RATIO: 10
#点击事件百分比
CLICK_RATIO: 80
#点击MONKEY_SPECIAL_POINT_LIST中的坐标 主要用于触发"返回"功能
CLICK_SPECIAL_POINT_RATIO: 10
#重启APP事件百分比
RESTART_APP_RATIO: 0
#特殊坐标长按(10秒)
LONG_PRESS_RATIO: 0
#Android Only按Home键事件百分比
HOME_KEY_RATIO: 0
#Gesture https://www.jianshu.com/p/095e81f21e07
DOUBLE_TAP_RATIO: 0
PINCH_RATIO: 0
UNPINCH_RATIO: 0
MONKEY_LIST:
#提高测试效率,点击以下点(x,y)时会触发"后退"操作,避免在一个页面停留时间太久
MONKEY_SPECIAL_POINT_LIST:
- '80,160'
#根据以下坐标长按10秒
LONG_PRESS_LIST:
- '980,560'
#设置不点击的区域, radius用来设置以下列坐标为圆心,不想点击的半径区域
MONKEY_BLACKLIST_POINT_LIST:
- 'radius,10'
- '0,0'
#小程序
MINI_PROGRAM:
MINI_PROGRAM_NAME: 学而思营业厅
MINI_PROGRAM_PROCESS: com.tencent.mm:appbrand1
#以下的内容很关键,而且需要根据不同的APP定制
CRITICAL_ELEMENT:
#Android 包名和启动的Activity
ANDROID_PACKAGE: com.***.***
ANDROID_MAIN_ACTIVITY: .Loading
#IOS Bundle ID com.apple.mobilesafari
IOS_BUNDLE_ID: com.tencent.xin
#手机桌面上显示的APP的名字
IOS_BUNDLE_NAME: 微信
#IPA名字的前缀
IOS_IPA_NAME: wechat
#构建XPATH需要的一些内容
#UI底部TabBar
ANDROID_BOTTOM_TAB_BAR_ID: com.***.***:id/mainTabLayout
IOS_BOTTOM_TAB_BAR_TYPE: XCUIElementTypeTabBar
#注意属性值要加引号''
ANDROID_CLICK_XPATH_HEADER: "//*[contains(name(), 'Text') and string-length(@text)<10] | //*[contains(name(), 'Image')] | //*[contains(name(), 'Button')]"
IOS_CLICK_XPATH_HEADER: '@visible="true" and string-length(@value)<30'
#注意属性值要加双引号""
ANDROID_USERNAME:
XPATH: '//*[@resource-id="com.***.***:id/account_num"]'
ACTION: input
VALUE: '137*********'
ANDROID_PASSWORD:
XPATH: '//*[@resource-id="com.***.***:id/pwd"]'
ACTION: input
VALUE: 'password123'
ANDROID_LOGIN_BUTTON:
XPATH: '//*[@resource-id="com.***.***:id/loginbtn"]'
ACTION: click
#IOS LOGIN_ELEMENT
IOS_USERNAME:
XPATH: '//*[@type="XCUIElementTypeTextField"]'
ACTION: input
VALUE: '130xxxxx456'
IOS_PASSWORD:
XPATH: '//*[@type="XCUIElementTypeSecureTextField" and @value="请输入登录密码"]'
ACTION: input
VALUE: '111111'
IOS_LOGIN_BUTTON:
XPATH: '//*[@type="XCUIElementTypeButton" and @name="登录" and @label="登录"]'
ACTION: click
LIST:
#待输入文件本的控制类型
INPUT_CLASS_LIST:
- android.widget.TextView
- XCUIElementTypeTextField
- XCUIElementTypeSecureTextField
#待输入的文本
INPUT_TEXT_LIST:
- '123'
- 'ABC'
#当发现App跳转到一下app时 会触发back键
PRESS_BACK_KEY_PACKAGE_LIST:
- 高德地图
- com.autonavi.minimap
- com.android.settings
#除了APP本身的包名外 根据以下包名判断是否跳出了APP.android当app跳转到以下app时被认为是合法,会继续遍历操作.
ANDROID_VALID_PACKAGE_LIST:
- com.miui.securitycenter
- com.android.server.telecom
- com.lbe.security.miui
- gallery
- packageinstaller
#ios 当app跳转到以下app时被认为是合法,会继续遍历操作
IOS_VALID_BUNDLE_LIST:
- 照片
#白名单
ITEM_WHITE_LIST:
- 确定
- 允许
- 退出
- 取消
- 已解决
#不点击包含以下文本的控件
ITEM_BLACKLIST:
- 客服
- 电话
- 不允许
- 拒绝
- 拍照
- 禁止
- 呼叫
- 低电量模式
- 关闭
#以下类型的元素及子元素不会被点击
IOS_EXCLUDE_BAR:
#手机状态栏
- XCUIElementTypeStatusBar
#键盘
- XCUIElementTypeKeyboard
#iOS不点击以下类型的元素
IOS_EXCLUDE_TYPE:
- XCUIElementTypeOther
- XCUIElementTypeKey
- XCUIElementTypeWindow
- XCUIElementTypeApplication
#android中不点击以下类型的元素
ANDROID_EXCLUDE_TYPE:
- android.widget.FrameLayout
# - android.widget.ImageButton
NODE_NAME_EXCLUDE_LIST:
- selected
- instance
- checked
- naf
- content
STRUCTURE_NODE_NAME_EXCLUDE_LIST:
#iOS
#- value
- name
#Android
- text
修改的地方并不多,大家可以用diff比较工具和原版的config.yml比较.
重点说一下这段配置:
原配置如下,含义既是遇到文本元素且<30的都点击
#注意属性值要加引号''
ANDROID_CLICK_XPATH_HEADER: 'string-length(@text)<30'
IOS_CLICK_XPATH_HEADER: '@visible="true" and string-length(@value)<30'
该段不支持如下写,比如我想如下写,可以跑起来,但拼接出来的"clickable elements xpath:"比较怪异且最后脚本端会报错停止,咨询后发现作者并不打算支持如下写法.
#注意属性值要加引号''
ANDROID_CLICK_XPATH_HEADER:
- "//*[contains(name(), 'Text') and string-length(@text)<10]"
- "//*[contains(name(), 'Image')]"
- "//*[contains(name(), 'Button')]"
IOS_CLICK_XPATH_HEADER: '@visible="true" and string-length(@value)<30'
最终查了下xpath语法知识,可以用 | 或来连接多个并列属性,这样跑不会报错且正常.这样就可以点击文本长度大于3小于10,和点击所有图片和Button元素.
#注意属性值要加引号''
ANDROID_CLICK_XPATH_HEADER: "//*[contains(name(), 'Text') and string-length(@text)>3 and string-length(@text)<10] | //*[contains(name(), 'Image')] | //*[contains(name(), 'Button')]"
IOS_CLICK_XPATH_HEADER: '@visible="true" and string-length(@value)<30'
五 执行
先通过adb命令检查小米Mix2真机是否连接正常,且确认真机开发者选项相关开启.
C:\Users\cmd>adb devices -l
List of devices attached
yourSerialNo device product:chiron model:MIX_2 device:chiron
启动appium server
C:\Users\cmd>appium --session-override
切到UICrawler-2.0.jar目录下执行即可.
D:\UICrawler>java -jar UICrawler-2.0.jar -f config.yml -u yourSerialNo
PS:
注意首次运行自动化脚本时候会向手机安装的相关有:
Unlock
Appium Android Input Manager
Appium Settings
io.appium.uiautomator2.Server.test
io.appium.uiautomator2.Server
六 执行结果
会按SerialNo+日期时间生成结果目录:
报告如图:
以上配置和jar包在win10和ubuntu18.04均测试正常通过.
其他配置项继续测试中...
七 运行UICrawler Monkey
截取部分相关说明,熟悉基本原生monkey的便可明白,下述配置既是指只运行点击事件的配置.
#设置事件百分比 各事件百分比之和为100
MONKEY:
#运行时间,以分钟计
MONKEY_RUNNING_TIME: 180
#以下各项值总和需为100
#滑动事件百分比
SWIPE_RATIO: 0
#点击事件百分比
CLICK_RATIO: 100
#点击MONKEY_SPECIAL_POINT_LIST中的坐标 主要用于触发"返回"功能
CLICK_SPECIAL_POINT_RATIO: 0
#重启APP事件百分比
RESTART_APP_RATIO: 0
#对应 LONG_PRESS_LIST:特殊坐标长按(10秒)
LONG_PRESS_RATIO: 0
#Android Only按Home键事件百分比
HOME_KEY_RATIO: 0
#Gesture https://www.jianshu.com/p/095e81f21e07
DOUBLE_TAP_RATIO: 0
PINCH_RATIO: 0
UNPINCH_RATIO: 0
MONKEY_LIST:
#提高测试效率,点击以下点(x,y)时会触发"后退"操作,避免在一个页面停留时间太久
MONKEY_SPECIAL_POINT_LIST:
- '70,140'
#根据以下坐标长按10秒
LONG_PRESS_LIST:
- '980,560'
#设置不点击的区域, radius用来设置以下列坐标为圆心,不想点击的半径区域
#MONKEY_BLACKLIST_POINT_LIST:
#- 'radius,10'
#- '0,0'
启动appium server
C:\Users\cmd>appium --session-override
传参-m 即可运行配置中的monkey相关设置
java -jar UICrawler-2.0.jar -f config.yml -u yourSerialNo -m
Tips
作者调起的是非原生monkey,所以当你发现无法正常关掉UICrawler Monkey,一直在手机中继续跑点击的时候,使用
# Linux下
adb shell ps |grep monkey
# windows cmd下
adb shell ps | findstr monkey
# 或
adb sehll ps | find "monkey" 找到返回的进程号
#然后 kill掉该手机内原生monkey进程
adb shell kill [刚才查到的进程号]
# 如windows下 原生monkey类似com.android.commands.monkey:
adb shell ps| findstr monkey
USER PID PPID VSIZE RSS WCHAN PC NAME
shell 13846 1032 2073652 51480 futex_wait 7f900d7ef0 S com.android.commands.monkey
是找不到该进程,也甭想kill掉的, 我们可以 ps -ef|grep UICrawler 相关结束掉本机脚本端的那个java进程也就是 . "java -jar UICrawler-2.0.jar -f config.yml -u yourSerialNo -m" 该进程
monkey配置部分说明1
关于坐标查看,可以打开开发者选项,"输入"该节下的 "指针位置".这样就可以看到坐标系了.
MONKEY_LIST:
#提高测试效率,点击以下点(x,y)时会触发"后退"操作,避免在一个页面停留时间太久
MONKEY_SPECIAL_POINT_LIST:
- '80,160'
#设置不点击的区域, radius用来设置以下列坐标为圆心,不想点击的半径区域
MONKEY_BLACKLIST_POINT_LIST:
- 'radius,10'
- '0,0'
第一个坐标'80,160',是左上的一般安卓app里的"返回"区域,
第二个坐标 - 'radius,10' - '0,0' ,这里 0,0 的话 应该不就是app界面左上区域起始点, 然后 x y偏移10 画个圆 ,不又是一般安卓app里的 "返回"区域?
这样 这两个 第1个 和 第3个不就冲突了?
这时如果,第1和2冲突时,以2为准 . 即以上效果为不点击左上那个区域, 也就是一般的app返回区域.
monkey配置部分说明2
#设置事件百分比 各事件百分比之和为100
MONKEY:
#运行时间,以分钟计
MONKEY_RUNNING_TIME: 180
#以下各项值总和需为100
#滑动事件百分比
SWIPE_RATIO: 10
#点击事件百分比
CLICK_RATIO: 80
#点击MONKEY_SPECIAL_POINT_LIST中的坐标 主要用于触发"返回"功能
CLICK_SPECIAL_POINT_RATIO: 10
#重启APP事件百分比
RESTART_APP_RATIO: 0
#对应 LONG_PRESS_LIST:特殊坐标长按(10秒)
LONG_PRESS_RATIO: 0
#Android Only按Home键事件百分比
HOME_KEY_RATIO: 0
#Gesture https://www.jianshu.com/p/095e81f21e07
DOUBLE_TAP_RATIO: 0
PINCH_RATIO: 0
UNPINCH_RATIO: 0
MONKEY_LIST:
#提高测试效率,点击以下点(x,y)时会触发"后退"操作,避免在一个页面停留时间太久
MONKEY_SPECIAL_POINT_LIST:
- '70,140'
#根据以下坐标长按10秒
LONG_PRESS_LIST:
- '980,560'
#设置不点击的区域, radius用来设置以下列坐标为圆心,不想点击的半径区域
#MONKEY_BLACKLIST_POINT_LIST:
#- 'radius,10'
#- '0,0'
该节为所有UICrawler Monkey配置
1 MONKEY: 该节 要注意所有事件比率百分比之和要为100,
2 MONKEY_LIST: 中的 "MONKEY_SPECIAL_POINT_LIST: "对应 MONKEY:节的"#点击MONKEY_SPECIAL_POINT_LIST中的坐标 主要用于触发"返回"功能
CLICK_SPECIAL_POINT_RATIO: 10"
3 MONKEY_LIST: 中的 "LONG_PRESS_LIST:" 对应 对应 MONKEY:节的" #对应 LONG_PRESS_LIST:特殊坐标长按(10秒)
LONG_PRESS_RATIO: 0"
那么上述配置的意思就是,执行点击事件80%,执行滑动事件10%,点击特殊区域坐标事件10%
八 结语
之前一直用AppCrawler 也很优秀,但无奈作者老大搞学院培训,无心维护和深入继续开发,支持也一直停留在appium1.7.0.
这也就算了,答应过的放出来打算做的特性都还没兑现....
比较使用这两个工具,执行稳定性上UICrawler可以连续跑很久(我最长跑了1小时回来还在继续跑且当前脚本配置来看截图执行的点击比较细腻且有规律),且脚本执行端不会报错,但AppCrawler 10次 会有个3次左右,脚本执行端会报错且无法继续执行下去,另有些配置效果AppCrawler 我并未完全吃透和试验出来.
补充说明
2018年6月29日追加
目前时间截点的config版本,该配置参数MONKEY_RUNNING_TIME: 6 已被CRAWLER_RUNNING_TIME 合并。请已官方github发布为准。
cmd@TR:~/UICrawler$ java -jar UICrawler-2.0.jar -h
16:41:03.088 [main] INFO Crawler - -h Print this usage information
-a Android package's main activity
-b iOS bundle id
-c Maximum click count
-d Maximum crawler UI depth
-f Yaml config file
-i ignore crash
-l loop count
-m run monkey
-p Android package name
-r Crawler running time
-t Appium port
-u Device serial
-v Version
-w WDA port for ios
-p 指定package 就会保证不退出app 或者退出APP了 能自己再重起.
-l loop count 循环次数,即一个Crawler running time遍历时间结束后,继续再跑几个Crawler running time。比如遍历时间6分钟,6分钟结束后 ,如果-l 是3 那就继续再跑2遍6分钟遍历,共3次。
#当发现App跳转到以下app时 会触发back键
PRESS_BACK_KEY_PACKAGE_LIST:
- 高德地图
- com.autonavi.minimap
- com.android.settings
getpacgesource 里返回的值 只要contains 关键字 就trigger back key 。即遇到当前被遍历的界面上包含配置的关键字即会触发back键。
疑惑与答疑
那这段配置遇到以下app 就back 是为了什么效果?跳到高德以后 会返回到app,不然会一直在高德里遍历。
..................... 那不和 -p 一样的效果 (-p 发现遍历的不是指定app了 也要重起app)
不一样啊,重启launch app 和触发返回 操作不一样 你想想是不是。
那就是面向两种场景的处理,保证不跳出遍历app。
补充记录:
2018年10月24日
已升级为appium1.9.1 ,在ubuntu18.04.1 windows10 升级后,均重跑UICrawler2.21 config 配置不变成功
升级记录
https://testerhome.com/topics/12988#reply10
(以上为win10版本且带支持做win32 uwp win应用UI自动化的appium1.9.1升级方式.)