自动化工具 MixMonkey 基于 Android Monkey

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

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若应用崩溃进程退出则无法重新进入被测模块继续测试。(2whitelist文件首个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 小白能否问问具体改动的代码?以及二次开发的过程啊

楼主有计划开源吗

匿名 #6 · 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

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