1.Monkey简介
- Monkey是Android系统自带的自动化测试工具;
- 可以随机模拟用户的一系列操作,比如触屏、滑动和系统按键等;
- 通过长时间执行,完成对App的稳定性测试,检测程序是否出现异常;
- Monkey在Android系统的存放路径:
/system/framework/monkey.jar
2.Monkey启动
- 检查Monkey命令:
adb shell type monkey
意思是monkey是/system/bin/monkey这个可执行文件的别称,
当我们执行adb shell monkey时运行的程序为/system/bin/monkey这个文件; - 所以Monkey启动使用了Android自带的
/system/bin/monkey这个shell脚本;
# Script to start "monkey" on the device, which has a very rudimentary
# shell.
#
#shell源码简单分析:
##当前笔者使用的测试机系统是Android6.0.1,不同Android版本shell脚本略有区别,但主体是一样的
base=/system
##设置CLASSPATH环境变量,指向Monkey.jar包的所在路径;
export CLASSPATH=$base/framework/monkey.jar
##trap捕获`HUP`中断信号,""表示捕获信号后什么都不做,以确保在脚本运行期间不会因为终端窗口关闭而中断;
trap "" HUP
##exec关键字表示在当前shell进程中替换启动app_process,
##app_process(c++程序)是用于启动Java进程的特殊工具,
##它的作用类似于java命令,但在Android中,使用app_process启动Java进程可以更好地集成到Android系统;
##此时$base/bin参数指定的是app_process工具所在的路径;
##monkey的主要业务逻辑在monkey.jar包中的字节码文件中,app_process会读取CLASSPATH环境变量值,
##找到monkey.jar文件,从中查找作为命令行参数的com.android.commands.monkey.Monkey类,
##app_process会加载这个Monkey类到ART虚拟机中并开始执行Java程序;
##这样就可以带着在终端写好的参数启动Monkey了。
exec app_process $base/bin com.android.commands.monkey.Monkey "$@"
##总结一下:monkey先由shell脚本程序启动,shell接着使用exec命令替换成一个新的程序app_process,
##再接着由app_process程序创建ART虚拟机实例;
##然后app_process程序会根据命令行参数中传递的参数,再去加载Java程序,
##此时位于/system/framework/monkey.jar这个jar文件中的Monkey类(字节码dex格式)
##会被加载到ART虚拟机内存中,Monkey类是Java程序的入口类,它的静态方法main()会被调用。
- 得益于Android自带的shell脚本,我们可以在终端通过"adb shell monkey -参数.."启动测试;
- 命令示例:
adb shell monkey --ignore-security-exceptions --ignore-crashes -v 500 - 启动成功终端有日志输出,手机出现随机自动操作;
- 执行设备的连接方式
- USB有线连接手机,终端启动执行,关闭终端窗口Monkey可继续执行;
- USB有线连接手机,终端启动执行,拔掉电源线Monkey执行停止;
adb connect无线连接手机,电源插拔、终端关闭均不影响执行,
这种方式多用于日常测试,可以用插座电源给手机充电防止放电过快,手机关机。
3.Monkey启动参数介绍
- 查看参数使用指南
adb shell monkey -help - -p 指定待测App包名,可添加多个应用,指定多个-p;
(adb shell pm list packages可查看当前测试机安装的App的包名列表)
adb shell monkey -p com.eg.android.AlipayGphone -p com.tencent.mm -v 1000 - -v 如上示例,加-v可以启用详细输出模式(Verbose Mode),以在终端看到更详细的运行日志;
还可以升级log详细等级,-v -v 和 -v -v -v逐渐增加log详细程度、覆盖activity事件信息;
adb shell monkey -p com.eg.android.AlipayGphone -p com.tencent.mm -v -v -v 1000 - COUNT 设置随机事件操作次数;
例如上例中的1000; - -c 如果您通过这种方式指定一个或多个类别,Monkey将仅允许系统访问其中一个指定类别中所列的Activity,很少用到这个参数; 要指定多个类别,多次使用-c选项,每个类别对应一个-c选项;
看了下源码,-c对应一个名为mMainCategories的ArrayList对象,执行时若不指定-c参数,默认添加了两个类;
- 设置事件百分比的参数
设置不同类型操作事件在本次测试过程中占总操作数的百分比;--pct-touch <percent>:设置触摸事件的权重百分比(单击事件)--pct-motion <percent>:设置直线滑动事件的权重百分比--pct-trackball <percent>:设置轨迹球事件的权重百分比(曲线滑动)--pct-syskeys <percent>:设置系统按键(这些按键通常预留供系统使用,例如“主屏幕”、“返回”、“发起通话”、“结束通话”或“音量控件”--pct-nav <percent>:基本导航事件(上下左右方向键)的权重百分比--pct-majornav <percent>:主要导航事件(例如返回键、菜单键)的权重百分比--pct-appswitch <percent>:调整Activity启动次数所占百分比。Monkey会以随机间隔发起 startActivity()调用,以最大限度地覆盖软件包中的所有Activity--pct-flip <percent>:设置设备翻转事件的权重百分比--pct-anyevent <percent>:其它类型事件的权重百分比 (这包括所有其他类型的事件,例如按键、设备上的其他不太常用的按钮等等)--pct-pinchzoom <percent>:设置缩放手势事件的权重百分比--pct-permission <percent>:设置请求权限事件的权重百分比--pct-rotation <percent>:设备旋转事件的权重百分比 (-help信息中没显示,源码中有)
可根据待测应用特点指定不同事件类型的占比,但总百分比要是100%,否则启动执行会报错;
##示例
adb shell monkey -p com.tencent.mm --pct-anyevent 0 --pct-appswitch 3 --pct-flip 0 --pct-majornav 0 --pct-motion 25 --pct-syskeys 12 --pct-nav 0 --pct-permission 0 --pct-pinchzoom 4 --pct-rotation 0 --pct-touch 55 --pct-trackball 0 -v 500
- 设置忽略参数
当测试过程中出现一些异常情况时,Monkey默认会停止,
此时可以指定一些忽略异常的参数,让Monkey继续执行,以达到预期测试时长;
`--ignore-crashes`:忽略应用程序崩溃(FATAL EXCEPTION等)
`--ignore-timeouts`:忽略应用程序长时间无响应、应用程序发生ANR(Application No Responding)错误
`--ignore-security-exceptions`:忽略安全异常
`--kill-process-after-error`:在发生错误后杀死应用进程(以免干扰测试的继续执行)
`--monitor-native-crashes`:监视应用程序在Native层发生的崩溃,并在崩溃发生时生成崩溃报告
`--ignore-native-crashes`:忽略应用Native层发生奔溃
例如当不指定任何忽略参数时,例如App遇到FATAL EXCEPTION,monkey会自动退出;
此时若添加指定
--ignore-crashes参数,出现异常后会继续执行;
adb shell monkey -p com.xiaomi.autotestapk --pct-anyevent 0 --pct-appswitch 3 --pct-flip 0 --pct-majornav 0 --pct-motion 25 --pct-syskeys 12 --pct-nav 0 --pct-permission 0 --pct-pinchzoom 4 --pct-rotation 0 --pct-touch 56 --pct-trackball 0 --ignore-crashes --ignore-timeouts --ignore-security-exceptions --ignore-native-crashes --kill-process-after-error -v 3000
一般以上参数均会添加。
-
--bugreport参数
如上忽略参数虽然跳过了App异常情况,但相关崩溃信息可以通过--bugreport参数将log存在/sdcard下; 当出现异常时,会自动存储相关崩溃信息;
adb shell monkey -p com.xiaomi.autotestapk --pct-anyevent 0 --pct-appswitch 3 --pct-flip 0 --pct-majornav 0 --pct-motion 25 --pct-syskeys 12 --pct-nav 0 --pct-permission 0 --pct-pinchzoom 4 --pct-rotation 0 --pct-touch 56 --pct-trackball 0 --ignore-crashes --ignore-timeouts --ignore-security-exceptions --ignore-native-crashes --kill-process-after-error --bugreport -v 3000 -
--pkg-blacklist-file PACKAGE_BLACKLIST_FILE:指定包名黑名单文件的路径
--pkg-whitelist-file PACKAGE_WHITELIST_FILE:指定包名白名单文件的路径
指定不测的App和待测的App,适合整机测试任务,一般使用较少。 -
Monkey还可以添加定制脚本
可以依据Monkey的API添加执行指定流程,一般以坐标形式完成操作;--setup scriptfile:在Monkey测试之前执行指定的脚本文件
-f scriptfile [-f scriptfile] ...:指定要执行的脚本文件
--randomize-script:随机选择要执行的脚本文件
使用较少,一般如果有定制需求,可以python+uiautomator+Monkey来完成,编写执行也较方便。 -
-s
-s SEED:指定随机数生成器的种子
若不添加,Monkey会自动分配一个seed值;
下次执行Monkey若在命令行指定-s 1703576515248,则两次事件操作序列一致,方便bug回验。 -
--throttle MILLISEC
指定操作事件间的时间间隔,单位毫秒,默认是0会尽快完成每次操作;
可根据需求执行间隔时长,以指定测试强度;
一般可以根据 COUNT*throttle 计算本次Monkey测试的大概时长。 -
--hprof
如果设置此选项,则会在Monkey事件序列之前和之后立即生成分析报告;
这将在data/misc路径下生成大型(约为 5Mb)文件,因此请谨慎使用。
4.Monkey停止
- 执行完成所有事件,Monkey会自动停止,并给出提示;
- 若想中途停止,可以使用adb命令;
adb shell ps | grep monkey
adb shell kill -9 "port"杀掉上步返回的端口值即可。
5.测试结束后的日志分析
Monkey执行结束后可以从不同位置获取异常log信息,观测被测应用的稳定性情况;
- 执行时可以将Monkey执行日志重定向到指定文件,保存执行相关信息;
adb shell monkey -p com.xiaomi.autotestapk --pct-anyevent 0 --pct-appswitch 3 --pct-flip 0 --pct-majornav 0 --pct-motion 25 --pct-syskeys 12 --pct-nav 0 --pct-permission 0 --pct-pinchzoom 4 --pct-rotation 0 --pct-touch 56 --pct-trackball 0 --ignore-crashes --ignore-timeouts --ignore-security-exceptions --ignore-native-crashes --bugreport -v -v -v 3000 > /home/ll/anr/log.txt 2>&1
可以在log文件中搜索"CRASH","ANR "等关键字定位异常信息;
还可以将log日志存储在执行手机中:
adb shell monkey -p com.xiaomi.autotestapk --pct-anyevent 0 --pct-appswitch 3 --pct-flip 0 --pct-majornav 0 --pct-motion 25 --pct-syskeys 12 --pct-nav 0 --pct-permission 0 --pct-pinchzoom 4 --pct-rotation 0 --pct-touch 56 --pct-trackball 0 --ignore-crashes --ignore-timeouts --ignore-security-exceptions --ignore-native-crashes --bugreport -v -v -v 3000 "> /sdcard/log.txt 2>&1" - 若执行时指定了
--bugerport参数,可在/sdcard下找到anr_包名、app_crash包名XXX的文件;
- 若设备已root,可以在
/data中找到不同类型异常信息;
/data/anranr问题日志;
/data/tombstonesTombstone Crash (Native层异常);
/data/dontpanicKernel Panic(Kernel层,Linux内核空间异常) - 若设备没有root,可以使用
adb bugreport命令,获取相关log;
FS/data目录下:
也可以辅助查看异常信息;
以上异常信息均可以利用如python脚本文件自动获取,方便收集。