【Android稳定性测试】Monkey基本使用方法详细介绍

1,215 阅读9分钟

1.Monkey简介

  • Monkey是Android系统自带的自动化测试工具;
  • 可以随机模拟用户的一系列操作,比如触屏、滑动和系统按键等;
  • 通过长时间执行,完成对App的稳定性测试,检测程序是否出现异常;
  • Monkey在Android系统的存放路径:/system/framework/monkey.jar     image.png

2.Monkey启动

  • 检查Monkey命令: adb shell type monkey     image.png
    意思是monkey是/system/bin/monkey这个可执行文件的别称,
    当我们执行adb shell monkey时运行的程序为/system/bin/monkey这个文件;
  • 所以Monkey启动使用了Android自带的/system/bin/monkey这个shell脚本;     image.png
# 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
  • 启动成功终端有日志输出,手机出现随机自动操作;     image.png
  • 执行设备的连接方式
    • USB有线连接手机,终端启动执行,关闭终端窗口Monkey可继续执行;
    • USB有线连接手机,终端启动执行,拔掉电源线Monkey执行停止;
    • adb connect 无线连接手机,电源插拔、终端关闭均不影响执行,
      这种方式多用于日常测试,可以用插座电源给手机充电防止放电过快,手机关机。

3.Monkey启动参数介绍

  • 查看参数使用指南
    adb shell monkey -help     image.png
  • -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参数,默认添加了两个类;
    image.png
  • 设置事件百分比的参数
    设置不同类型操作事件在本次测试过程中占总操作数的百分比;
    • --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%,否则启动执行会报错; image.png
##示例
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会自动退出;     image.png     此时若添加指定--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下; 当出现异常时,会自动存储相关崩溃信息;     image.png
    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添加执行指定流程,一般以坐标形式完成操作;     image.png --setup scriptfile:在Monkey测试之前执行指定的脚本文件
    -f scriptfile [-f scriptfile] ...:指定要执行的脚本文件
    --randomize-script :随机选择要执行的脚本文件
    使用较少,一般如果有定制需求,可以python+uiautomator+Monkey来完成,编写执行也较方便。

  • -s
    -s SEED:指定随机数生成器的种子
    若不添加,Monkey会自动分配一个seed值; image.png
    下次执行Monkey若在命令行指定-s 1703576515248,则两次事件操作序列一致,方便bug回验。

  • --throttle MILLISEC
    指定操作事件间的时间间隔,单位毫秒,默认是0会尽快完成每次操作;
    可根据需求执行间隔时长,以指定测试强度;
    一般可以根据 COUNT*throttle 计算本次Monkey测试的大概时长。

  • --hprof
    如果设置此选项,则会在Monkey事件序列之前和之后立即生成分析报告;
    这将在data/misc路径下生成大型(约为 5Mb)文件,因此请谨慎使用。

4.Monkey停止

  • 执行完成所有事件,Monkey会自动停止,并给出提示;
    image.png
  • 若想中途停止,可以使用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" image.png
  • 若执行时指定了--bugerport参数,可在/sdcard下找到anr_包名、app_crash包名XXX的文件;
    image.png
  • 若设备已root,可以在/data中找到不同类型异常信息;
    /data/anr anr问题日志;
    /data/tombstones Tombstone Crash (Native层异常);
    /data/dontpanic Kernel Panic(Kernel层,Linux内核空间异常)
  • 若设备没有root,可以使用adb bugreport命令,获取相关log;
    image.png
    FS/data目录下:
    image.png
    也可以辅助查看异常信息;

以上异常信息均可以利用如python脚本文件自动获取,方便收集。