自动化工具 MixMonkey 基于 Android Monkey

wenxiaomao · 2018年12月31日 · 最后由 刘 回复于 2020年02月03日 · 8243 次阅读

MixMonkey 基于 Android Monkey

概述

Android 自动化一般使用 uiautomator 或者 monkey 等工具模拟用户操作,uiautomator 可以定制自已的 case,monkey 可以像小盆友一样乱点
稳定性测试一般需要长时间的运行,定制 case 的方法并不能很好的解决稳定性问题,因为总有 case 考虑不到的情况,当 case 过多,若界面改版发生变化,case 维护成本也是很高的,有时测试任务排期紧,APP 提测后要尽快上线,可能根本没有时间修改 case
随机 + 主要功能定制 case 结合是比较好的方式,既能保证覆盖率,也能保证随机性,这也是我们当前的方案

模块稳定性测试 / 模块 bug 验证

有时某个模块出现问题,若不能知道复现路径,又想验证开发的 change 是否修复了这个问题,就比较麻烦了,不同的应用需要根据自身 APP 定制模块测试策略,通用性不强
举一个最近的测试例子,有一个直播插件需要集成到我们的应用中,模块入口就像微信中的三方服务一样(像某东,某团,某多多),要先进入一个界面,之后向下滑动才能看到入口,然后只想测试这个模块中的功能,尴尬啊,闹心啊,咋办啊
稳住,别慌,不要乱
凭借本猫的第六感,之前就预感会有这样的需求发生在我的身上,于是就在今年双 12 的时候开始了这个工具的开发(双 12 狠心买了个移动硬盘),由于小米 Mix 手机很酷酷,因此将其以 Mix 命名,此工具是以 android monkey 为基础,二次开发

为什么要改 monkey?

通用,monkey 是 google 提供的测试方案,各厂商的设备都会兼容
无需签名或 root 设备,由于是和源码一同编译后生成的文件,所以可以做很多普通应用无法做的事情
先看一下如下工具的对比,可以找到我们需要完善和优化的地方

长时间稳定性测试 monkey uiautomator2 mixmonkey
实时异常检测 支持 不支持(需要系统签名) 支持
指定测试界面(不包括定制 case) 不支持 不支持 支持
低内存设备后台优化杀掉测试进程 不会 可能会(需要加入 ROM 白名单) 不会
测试覆盖率 随机 随机(依赖 case 数量) 高
安静的测试 不支持 不支持 支持
指定 case(不包括-f) 不支持 支持 不支持

通过上面个表格,可以看出,在定制 case 的前提下,uiautomator2 是比较好的工具,但是要做需要权限的事情,uiautomator2 就很依赖系统签名,通用性不够好,uiautomator1 可以考虑一下 :)

基于当前 monkey 和 uiautomator 的一些问题,将 monkey 做了修改,现已实现的功能如下
1.通用性,无需 root,不依赖签名
2.兼容性,基于 AOSP android-6.0.1_r1 monkey,一个 jar 包兼容 android5-9,(--mix)
3.实时异常检测,保存异常日志到/sdcard/mixmonkey 下,(--savelog)
4.优化了 Touch 事件,获取界面控件操作,点击更加准确
5.优化了 Motion 事件,实现真正意义上的上下左右滑动,当前 Motion 事件,有小概率为原生 Motion,其他是上下左右滑动
6.优化了 Back 事件概率低问题,加入 Back 事件百分比,(--pct-syskeys-back)
7.模块测试,activity 白名单,支持 Deeplink,文件可以使用 # 注释,读取文件时将忽略 # 开头的行,(--activity-whitelist-file)
8.安静测试,加入 Mute 事件百分比,(--pct-syskeys-mute)
9.防止跳出,每 10 个事件循环会检测一次当前界面是否在测试包中,若不在,则拉起被测应用(1.0.3 版本添加)
10.将 KEYCODE_MENU 添加到 syskeys 中

默认事件百分比 --mix

事件 百分比 参数 备注
ANYTHING 0 --pct-anyevent
APPSWITCH 3 --pct-appswitch
BACK 15 --pct-syskeys-back
FLIP 0 --pct-flip
MAJORNAV 0 --pct-majornav
MOTION 18 --pct-motion 加--mix 参数后,上下左右滑动,仅小概率原生 Motion
MUTE 3 --pct-syskeys-mute
NAV 0 --pct-nav
PERMISSION 0 --pct-permission
PINCHZOOM 3 --pct-pinchzoom
ROTATION 5 --pct-rotation
SYSOPS 3 --pct-syskeys 加--mix 参数后,只有 KEYCODE_HOME,KEYCODE_MENU
TOUCH 50 --pct-touch
TRACKBALL 0 --pct-trackball

使用方法

adb shell CLASSPATH=/sdcard/mixmonkey.jar exec app_process /system/bin com.android.commands.monkey.Monkey -h

usage: monkey [-p ALLOWED_PACKAGE [-p ALLOWED_PACKAGE] ...]
              [-c MAIN_CATEGORY [-c MAIN_CATEGORY] ...]
              [--ignore-crashes] [--ignore-timeouts]
              [--ignore-security-exceptions]
              [--monitor-native-crashes] [--ignore-native-crashes]
              [--kill-process-after-error] [--hprof]
              [--pct-touch PERCENT] [--pct-motion PERCENT]
              [--pct-trackball PERCENT] [--pct-syskeys PERCENT]
              [--pct-nav PERCENT] [--pct-majornav PERCENT]
              [--pct-appswitch PERCENT] [--pct-flip PERCENT]
              [--pct-anyevent PERCENT] [--pct-pinchzoom PERCENT]
              [--pct-permission PERCENT]
              [--pkg-blacklist-file PACKAGE_BLACKLIST_FILE]
              [--pkg-whitelist-file PACKAGE_WHITELIST_FILE]
              [--wait-dbg] [--dbg-no-events]
              [--setup scriptfile] [-f scriptfile [-f scriptfile] ...]
              [--port port]
              [-s SEED] [-v [-v] ...]
              [--throttle MILLISEC] [--randomize-throttle]
              [--profile-wait MILLISEC]
              [--device-sleep-time MILLISEC]
              [--randomize-script]
              [--script-log]
              [--bugreport]
              [--periodic-bugreport]
              [--permission-target-system]
    mixmonkey [--mix] 存在此参数则执行mixmonkey,否则执行原生monkey
    mixmonkey [--savelog] 存在此参数则发生crash或anr时将日志保存在/sdcard/mixmonkey下面,包括logcat.log logstack.log traces.txt screenshot.png
    mixmonkey [--running-minutes MINUTES] 运行时间(单位分钟),若此参数和COUNT共存,则以最先结束的为准
    mixmonkey [--activity-whitelist-file ACTIVITY_WHITELIST_FILE] 存在此参数则只在配置的activity中执行测试,请注意,(1)若应用崩溃,进程退出,则无法重新进入被测模块继续测试。(2)whitelist文件首个activity必须是模块的入口activity,不支持入口在Fragment中,与其他Fragment共用一个Activtiy的情景,如TAB页,此时需要将入口设置成进入模块后的activity
    mixmonkey [--pct-syskeys-back PERCENT] Back事件百分比
    mixmonkey [--pct-syskeys-mute PERCENT] Mute事件百分比
    mixmonkey [--version] 版本信息
              COUNT

将 mixmonkey.jar push 到/sdcard/下面

启动命令

adb shell CLASSPATH=/sdcard/mixmonkey.jar exec app_process /system/bin com.android.commands.monkey.Monkey -p xxx --mix --savelog --activity-whitelist-file /sdcard/whitelist --running-minutes 60 --ignore-crashes --ignore-timeouts --ignore-security-exceptions --ignore-native-crashes -vv --throttle 300 10000

下载地址 mixmonkey.jar

结尾

社区 zhangzhao_lenovo 大神之前曾做过fastmonkey的工具,之前使用过,感觉非常不错,但是由于不开源,有很多想适配当前业务的功能无法添加,于是决定发粪涂墙!从 0 到 1,从无到有,一边工作,一边改猴,12 月的最后两周真是非常不易

工具还在开发阶段,先提供一个稳定初版,欢迎大家提出宝贵建议,感激不尽!

说了题外话,我和阿联打了个赌,如果MixMonkey超过 50 个星他就请我吃一顿鱼,欢迎捧场:)

收工~~

本文为作者原创,如需转载,请注明出处,感谢

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 26 条回复 时间 点赞

非常感谢分享,楼主你的工程只有一个 jar 包啊?

对 simple 回复

是的

😀 已 start 小白能否问问具体改动的代码?以及二次开发的过程啊

楼主有计划开源吗

匿名 #24 · 2019年01月02日

这个 能对 webview 里的模块进行指定界面测试吗?比如我的 app 是混合应用,可能所有 web 页面的 activity 入口都是同一个,但是 web 里有很多模块,我想指定某个模块进行 monkey 测试可以吗

设置了五分钟,都十分钟了还在跑,没结束

我们的应用是原生的,webview 暂时还不支持,没有考虑到这个情景,感谢反馈!

对 heygrl 回复

请问同时设置事件数了吗,就是命令最后一个值,将他改为 10 试下呢

需要关注 android 不同版本的差异,用反射实现兼容,monkey 源码差异不大,android 的 uiautomation 可以了解下,可以看下 uiautomator 的源码实现获取控件,其他按照 monkey 的思路开发就可以

对 heygrl 回复

还在开发阶段,感谢关注:)

报错;SYS_KEYS has no physical keys but with factor 7.0%. 把--pct-syskeys 和--pct-syskeys-back 设置为 0 ,又不能正常执行,不加--mix 参数也卡着不动 是怎么回事?

对 TestMonkey 回复

哈喽,已经找到问题原因,代码写错了-。- 在带虚拟按键的手机上就会暴露出这个问题,已经修改,请更新 1.0.3 版本,感谢反馈:)

对 heygrl 回复

哈喽,已经修改,请更新 1.0.3 版本,现在如果--running-minutes 和总事件数 COUNT 共存,则以--running-minutes 为主,COUNT 无效

15楼 已删除

开源吧。

whitelist.txt 格式是怎样的?

楼主,在吗?
请教下:
whitelist.txt 白名单可以加多个 activity 吗?
monkey 过程中,白名单页面 activity 能点进入,非白名单页面 activity 点不进入是如何实现的哈?

对 jint 回复

activity 的完整的名字,比如 com.xxx.Activity
https://developer.android.com/reference/android/content/ComponentName#getClassName()
此参数设计是为了模块测试,whitelist.txt 的首行需要写模块入口的 Activity,当 activity resume 的时防止跳出,模块中所有用到 Activity 都要填写到白名单中,比如
com.xxx.MainActivity
com.xxx.SubActivity1
com.xxx.SubActivity2
com.xxx.SubActivity3

测试时,需要先手动进入到被测模块,启动测试后会只在模块中测试,如果出现跳出模块,则可能出现 3 种问题
1.APP 崩溃了,可以抓到日志,在/sdcard/mixmonkey
2.APP 闪退了,可能无法抓到日志
3.mixmonkey 出现 bug 了 -。- 请帮忙留言反馈,感激不尽

跳出模块后,不会重新进入测试模块(由于环境多样,所以无法再次进入模块),跳出后可能因为当前界面没有在白名单中,也无法继续测试,此时应该停止测试,kill monkey 进程即可,或者启动 monkey 时直接加参数--kill-process-after-error

仅楼主可见

请教下:
activity resume 的时防止跳出,monkey 过程中,白名单页面 activity 能点进入,非白名单页面 activity 点不进入是如何实现的哈?

对 wenxiaomao 回复

感谢
“mixmonkey 测试覆盖率高;优化了 Touch 事件,获取界面控件操作,点击更加准确” 指定页面 monkey 时,会覆盖 点击到页面每个控件操作吗?

你好,请问下如何做到各个 api 的兼容

你这也不开源啊

26楼 已删除

非常感谢楼主,之前差临门一脚跑通识别元素,通过在楼主这里获取的一些信息,反复的研究,终于搞定怎么识别元素了🎁

对 careysucci 回复

老哥,问点基本问题,方便加一下 QQ 吗,906999953

1楼 已删除
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册。