背景
智能遍历,即通智能化的规则来访问APP的UI页面;之所以要考虑这种方式,主要是monkey随机测试,随机性太强,覆盖率不好衡量;不方便进行版本之间的对比,因此考虑其他智能遍历方案,备选的有三种方案“UI自动化实现/appcrawler自动遍历/fastbot智能遍历”
方案对比
UI自动化实现
- 优点
1
2定制化程度高,可控
可进行持续集成 - 缺点
1
工作量大,稳定性差,实现难度高
- 优点
appcrawler自动遍历
- 优点
1
2
3
4覆盖率高,利用类爬虫机制能进行深度遍历,基本覆盖所有的页面
可进行策略定制,灵活性较高,使用成本较低
执行有HTML结果,支持Android和iOS渠道
支持持续集成; - 缺点
1
执行策略和版本数据相关性不大,无法利用历史策略数据
- 优点
fastbot智能遍历
- 优点
1
2
3
4
5
6
7
8
9覆盖率高,且有覆盖率指标,进行智能遍历,遍历策略较智能(每次遍历都会建模,利用深度学习会持续优化模型,作为驱动策略),现实意义较强;
可进行定制,灵活度较高,使用成本较低;
支持iOS和Android渠道;
可利用数据驱动,方便进行版本间的迭代,方便优化驱动策略;
支持持续集成;
利用monkey来遍历,执行较快,效率高;
支持非标准化控件,可以利用图像识别来进行断言;
每次的模型可复用,模型文件会自动存储在 /sdcard/fastbot_[包名].fbm,换设备或者版本可复用原有模型,保证策略完全一致;只需要放在相同的位置即可;
支持多设备 - 缺点
1
2
3需要第三方工具,进行性能监控,本身不支持;
无结果报告,只有打印的覆盖率指标,同时只有异常日志;
后期可能会收费,一旦收费,建议转solopi或者自研;
- 优点
综合考虑,最终决定采用fastbot,其中很大一个原因是其支持数据驱动,方便持续优化策略,同时据同事说shein也在使用;
fastBOT使用
大纲
1 | 安装/部署 |
安装/部署
- 部署Java环境
- 下载java jdk
- 配置Java环境变量:在系统变量中对JAVA_HOME、PATH、CLASSPATH进行配置:
- JAVA_HOME:C:\Program Files (x86)\Java\jdk1.8.0_91
- PATH:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin
- CLASSPATH:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar
- 部署Android环境
- 先部署Java环境
- 安装Android studio
- 通过Android studio 安装对应版本的Android sdk
- 添加Android环境变量:系统变量中添加ANDROID_HOME,PATH:
- ANDROID_HOME:C:\Users\gavin\AppData\Local\Android\Sdk
- PATH:%ANDROID_HOME%\platform-tools;%ANDROID_HOME%\tools;C:\Users\gavin\AppData\Local\Android\Sdk\build-tools\32.0.0(aapt命令的环境变量,其是apk解析程序)
- 将jdk包,pull到手机
- adb push * .jar /sdcard
- adb push libs/ * /data/local/tmp/
- 部署Java环境
使用指令
- 举例:
1
2
3IOS:tidevice xctest -B bytedance.FastbotRunner112.xctrunner -e BUNDLEID:com.TranssnetMusic.Boomplay -e duration:120 -e throttle:300 --debug
ANDROID:adb -s 037952588D000392 0442233974160287 shell CLASSPATH=/sdcard/monkeyq.jar:/sdcard/framework.jar:/sdcard/fastbot-thirdpart.jar exec app_process /system/bin com.android.commands.monkey.Monkey -p com.afmobi.boomplayer --agent reuseq --running-minutes 240 --throttle 500 -v -v --output-directory /sdcard/fast_data- 参数说明
1
2
3
4
5
6
7
8
9必填参数:
-s imei imei2:支持多设备
-p package_name:str;“adb shell pm list package”可获取APP包名
--agent reuseq :遍历模式,无需更改
--running-minutes 120:遍历时长,单位是min
--throttle 500:和monkey中的--throttle相同,为事件频率,建议500-800
选填参数:
--bugreport :#发生崩溃时打印的日志
--output-directory : /sdcard/xxx #输出目录的文件夹定制策略
- 限定词
限定自动化定位到的文本只能是apk字符串池中出现的文本,否则抛出异常
1
2
3操作:
aapt2 dump strings apk路径 > max.valid.strings :将apk中所有的字符创,加入到限定词文档
adb push max.valid.strings /sdcard:配置文件需要push到sdk卡才能生效 - 自定义事件执行顺序
应用于需要自定义执行顺序的场景(如登录),或者要保证一定要覆盖到的核心场景,实现方式如下:
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在pc端新建 max.xpath.actions 文件
编写事件序列的case,参考我提供的max.xpath.actions文件,文件编写好之后push到/sdcard的根目录;举例说明:
[
{
"prob":1, //事件发生概率,实际使用注释文件要删掉
"activity":"com.boomplay.ui.main.MainActivity", //作用的页面
"times":1, //重复次数
"actions":[ //具体步骤的执行,同时支持多个操作
{
"xpath":"//*[@text='Charts']", //尽量使用resource-id作为xpath路径,也可以组合使用比如"xpath": "//*[@resource-id='xxx'and @text='xx']"
"action":"CLICK", //动作支持的操作,必须大写(CLICK,LONG_CLICK,BACK,SCROLL_TOP_DOWN,SCROLL_BOTTOM_UP,SCROLL_LEFT_RIGHT,SCROLL_RIGHT_LEFT)
"text": "打开页面成功",
"clearText":false, //明文,可不带
"throttle":5000 //action间隔事件(ms)
},
{"xpath":"//*[@text='Artists']",
"action":"CLICK",
"throttle":5000}
]
}, //到不同的activity操作,需要新起一个对象
{
"prob":1,
"activity":"com.boomplay.ui.guide.GuideDialogSearchActivity",
"times":1,
"actions":[
{
"xpath":"//*[@text='Charts']",
"action":"CLICK",
"text": "打开页面成功",
"clearText":false,
"throttle":5000
},
{"xpath":"//*[@text='Artists']",
"action":"CLICK",
"throttle":5000}
]
},
]
配置白名单
作用:定制策略只在白名单页面内进行操作
1
2
3
4
5操作:
新建 awl.strings文件
在文件中写入Activity的名称,如:com.boomplay.ui.main.MainActivity
将文件push到手机/sdcard路径下,使用时,在执行命令尾部添加:
--act-whitelist-file /sdcard/awl.strings配置黑名单
作用:定制策略不允许访问黑名单页面
1
2
3
4
5操作:
新建 abl.strings文件
在文件中写入Activity的名称,如:com.boomplay.ui.main.MainActivity
将文件push到手机/sdcard路径下,使用时,在执行命令尾部添加:
--act-blacklist-file /sdcard/abl.strings黑白名单不能同时配置,非黑即白
定制需要屏蔽的按钮/区域
作用:如登防止登录后,中途退出
1
2
3
4
5
6
7
8
9
10
11
12新建max.widget.black文件,文件配置后,push到/sdcard路径下
[
{
"activity":"com.ss.android.xxx.MainActivity",
"xpath": "//*[@resource-id='com.xxx.go:id/aaa']"//通过元素控制不让访问
},
{
"activity":"com.ss.android.xxx.MainActivity",
"bounds": 0.5 //activity区域内50%区域不被点击,值为0-1
}
]通过tree屏蔽
原理配置xpath:查找匹配的控件,改变控件属性,从而使控件屏蔽
1
2新建max.tree.pruning文件,文件配置完后,push到/sdcard路径下
配置实例:建github提供的文件参考配置- 定制事件中模糊事件/突发性事件的占比
所谓的模糊事件,是指执行某个操作后(定制的action事件),模型会根据这个操作生成5-10个相关的操作的策略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19在max.config文件中增加模糊性事件,在总的事件中的占比,配置完成后,push到/sdcard路径
max.fuzzingRate = 0.01D //0.01为Fuzz事件的总概率
模糊事件,包含以下事件,(数字为配置事件在模糊性事件中的概率,以下数值为默认值,可定制):
max.doRotateFuzzing = 0.15
max.doAppSwitchFuzzing = 0.15
max.doTrackballFuzzing = 0.15
max.doNavKeyFuzzing = 0.15
max.doKeyCodeFuzzing = 0.15
max.doSystemKeyFuzzing = 0.15
max.doDragFuzzing = 0.5
max.doPinchZoomFuzzing = 0.15
max.doClickFuzzing = 0.7
在max.config文件中增加随机性事件(monkey随机性事件),在总的事件中的占比,配置完成后push到/sdcard路径下
max.startMutation = 0.3D //启动Fastbot立刻设置mutation的几率,默认30%
随机性事件,包含以下事件,(数字为默认概率,此概率为事件总概率,可定制):
max.doMutationAirplaneFuzzing = 0.001
max.doMutationMutationAlwaysFinishActivitysFuzzing = 0.1
max.doMutationWifiFuzzing = 0.001- 限定词
优化策略
- 输入内容优化
输入是用户主观意愿很强的行为,为保证输入的内容是有价值的,更添近真实场景,在覆盖输入场景做一些策略优化,以屏蔽乱输入内容
- 操作
1
2
3
4
5
6
7
8
9使用ADBKeyBoard在输入栏自动输入内容,屏蔽UI输入法:UI输入法,不同终端使用不同的输入法,不稳定(安装部署adbkeyboard见下方内容,基本所有的开源的自动化工具在输入这块都会封装输入法,为了方便复用和稳定,不建议调用手机的输入法);
输入随机字符串:pc建一个max.config文件;配置 max.config 中 max.randomPickFromStringList = false,最后将文件push到手机的/sdcard目录下;
从文件中随机读取字符串来输入:pc建一个max.config文件;配置 max.config 中 max.randomPickFromStringList = true,然后在建一个max.strings文件,里面放用来输入的字符串(每一行为一个对象);最后将max.config和max.strings文件push到手机的/sdcard目录下;
模糊输入:模糊输入和随机输入有点类似,不过有限定范围,fastbot模糊输入的限定规则如下:
50% 概率输入fuzzing.strings中某个string
35% 概率输入被测试 App 历史页面中text/desc文本内容(不存在max.fuzzing.strings文件时概率提高到85%)
15% 概率不输入
使用文件限定的模糊输入:将git项目中的test/max.fuzzing.strings文件push到手机/sdcard下,此文件存在模糊搜索策略及生效,文件里放想输入的字符串;
部署adbkeyboard
- [下载开源包](https://github.com/senzhk/ADBKeyBoard/archive/refs/heads/master.zip)
- 进入项目目录cd ADBKeyBoard
- 设置环境变量 export ANDROID_HOME=$HOME/Android/Sdk
- 在保证手机连接电脑,且赋予debug权限情况下,执行安装命令./gradlew installDebug
- 如果以上方式无法安装,请安装apk包:地址
apk反混淆
是什么:混淆指的是Java混淆编译,用以防止对源码的反编译破解;反混淆,类似于解密;使得配置在 不同版本的App中可以通用
1
2
3配置混淆映射文件max.mapping,push到手机/sdcard中,以建立混淆前后ID映射关系:
adb push resguard_mapping_NewsArticle_beta_version_v7.2.x_?????.txt /sdcard/max.mapping
配置反混淆文件,以自定义事件为例,在 max.xpath.actions 中配置混淆前的 resource-id,参考示例文件测试过程中自动截图
场景:当--throttle 事件频率>200时,配置了截图,会对测试过程中页面进行截图
1
2
3
4
5新建max.config配置文件,增加以下属性,配置完成后文件push到/sdcard路径下
max.takeScreenshot = true
max.takeScreenshotForEveryStep = true
max.saveGUITreeToXmlEveryStep =true
目录默认保存为手机端sdcard中,如需改变保存位置,在执行命令末尾添加 --output-directory 指定路径支持外链跳转
支持第三方的外链跳转,跳转到第三方应用,或者跳转到端内页面
1
2
3新建max.schema文件,增加配置如下,文件配置完后,push到/sdcard路径下
max.execSchema = true
max.execSchemaEveryStartup = true #每次启动app先执行schema应用自动授予权限
如boomplay需要获取通讯录/相机权限,fastbot启动时默认会一次性各所有权限,如需每次动态给权限,需要更改配置
1
2
3
4
5
6
7在max.config中增加以下配置,则不会自动给所有权限;文件配置完之后push到/sdcard路径下
max.grantAllPermission = false
动态给权限的方式是,在执行的adb命令尾部增加对应的android权限授予的指令:
-p com.android.packageinstaller
-p com.android.permissioncontroller
-p com.lbe.security.miui # for (miui android 10)
-p com.samsung.android.permissioncontroller # for (samsung android 10)fastbot压缩包提供了各类素材,用以在执行选取各类素材的场景中使用,如发带图片的buzz
1
2adb push data/fuzzing/ /sdcard
adb shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///sdcard/fuzzing
- 输入内容优化
结果分析
- 异常数据
crash:Crash会以追加方式写入/sdcard/crash-dump.log文件
anr:写入 /sdcard/oom-traces.log 文件 - 覆盖率统计:coverage = testedActivity / totalActivities * 100
testedActivity:本次测试的activity,会打印出来
totalActivities:总的activity,会打印出来
以上的所有activity,是不区分废弃,或者未使用的activity,为APP的所有的activity
- 异常数据
性能采集
性能采集,主要是采集内存/CPU的数据,从而来分析APP执行case时的性能
方法一
通过火山提供的APP性能分析工具进行监控:工具地址(火山引擎开始收费了,工具现在虽然免费,不排除未来收费,有使用风险)
方法二
借助其他的性能数据抓取工具,比如 OneApm, NewRelic(付费);或者支付宝的solopi;使用第三方工具可能会对结果有影响,最好能统一场景,保证结果一致;
- 常用操作
获取APP包名
1
aapt dump badging apk_path
使用maxim获取APPactivity
1
adb shell CLASSPATH=/sdcard/monkey.jar:/sdcard/framework.jar exec app_process /system/bin tv.panda.test.monkey.api.CurrentActivity 注意里面的文件需要push到手机对应的位置后才能使用
使用maxim查看当前页面的TREE结构,来获取配置需要id等。。
1
adb shell CLASSPATH=/sdcard/monkey.jar:/sdcard/framework.jar exec app_process /system/bin tv.panda.test.monkey.api.Dumptree
常见问题,查看帮助文档