Monkey 简介
Monkey 在英文里的含义是“猴子”,意如其名,其实就是模拟随机无目的的测试应用。通过长时间、快速的随机发送的事件流,对 Android 应用不断造成操作的压力。优化不好,兼容不好的应用很容易在这种快速的随机操作中出现一些严重的异常问题,比如 Crash(崩溃), ANR(无响应)等。
- Monkey 是一种命令行工具,Android 设备或模拟器中都自带该工具;
- 向被测应用发送伪随机事件流(如按键、触屏、手势等),且使用的事件流数据流是随机的,不能自定义;
- Monkey 使用 java 语言编写,名为 monkey.jar ,位于 /system/framework 目录;
- 通过 monkey 用随机重复的方式来对应用程序进行一些稳定性、健壮性方面的测试;
- 通过名为 monkey 的 shell 脚本启动执行,shell脚本的存放路径为: /system/bin/monkey;
- 通过 adb 连接设备或模拟器后执行 monkey 命令。
Monkey 命令
adb shell monkey [+ 命令参数] [指令数]
最简单的示例:
adb shell monkey 100 # 发送 100 个随机指令
上面的 monkey 命令发送了 100 个随机指令,因为并没有指定具体的应用包名。会在整个系统内随机执行。
Monkey 参数
最常用的参数
-
-p
用于约束限制,用此参数指定一个或多个包。指定包后,所有的随机指令都会针对该应用进行操作。(如何查找包名,请查看文章最后)
示例:
adb shell monkey -p com.huomaotv.mobile 100 # 对“火猫 TV”发送 100 个随机指令
接下来的 100 条指令都会在 火猫TV
应用内进行。不过注意,100 条指令会在极快的时间完成。
-
-v
用于指定反馈信息级别(信息级别就是日志的详细程度),总共分 3 个级别,以-v
参数在命令中的个数决定级别,-v
参数个数越多日志就越详细。- Level 1: 缺省值,仅提供启动提示、测试完成、最终结果及 Crash 日志等少量信息
adb shell monkey -p com.huomaotv.mobile -v 100
- Level 2: 提供较为详细的日志,包括每个发送到 Activity 的事件信息
adb shell monkey -p com.huomaotv.mobile -v -v 100
- *Level 3:最详细的日志,包括了测试中选中/未选中的Activity信息
adb shell monkey -p com.huomaotv.mobile -v -v -v 100
- Level 1: 缺省值,仅提供启动提示、测试完成、最终结果及 Crash 日志等少量信息
-
--throttle
每个事件结束后的间隔时间。用于降低系统压力。如果不指定,系统会尽快的发送事件序列
adb shell monkey -p com.huomaotv.mobile --throttle 300 100 # 每个指令间延时 300 毫秒
-
-s
指定测试的种子值(编号),如果两次的种子值相同,则两次测试的随机指令完全相同。主要用于回归和重现出现的 Bug。
这里稍微难以理解一点, 每次 monkey 命令的指令都是完全随机的,导致如果测试过程中发现问题,就无法复现。这也就导致开发修复问题之后,我们也无法确定之前的问题是否被修复。
为了保证能重现问题,在运行 monkey 指令的时候加一个 种子值,只要后续的指令带上该种子值,那么两次运行的随机命令完全一致。
示例:
[C:\~]$ adb shell monkey -p com.huomaotv.mobile -s 5555 -v 100
:Monkey: seed=5555 count=100
:AllowPackage: com.huomaotv.mobile
... # 其他日志省略
:Sending Touch (ACTION_DOWN): 0:(124.0,20.0)
:Sending Touch (ACTION_UP): 0:(114.721886,7.5346775)
// activityResuming(com.huomaotv.mobile)
:Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.huomaotv.mobile/.ui.main.activity.SplashActivity;end
// Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.huomaotv.mobile/.ui.main.activity.SplashActivity } in package com.huomaotv.mobile
:Sending Trackball (ACTION_MOVE): 0:(0.0,-3.0)
// activityResuming(com.huomaotv.mobile)
:Sending Touch (ACTION_DOWN): 0:(718.0,217.0)
:Sending Touch (ACTION_UP): 0:(720.0,201.25154)
:Sending Trackball (ACTION_MOVE): 0:(-2.0,1.0)
:Sending Touch (ACTION_DOWN): 0:(340.0,1100.0)
:Sending Touch (ACTION_UP): 0:(333.30652,1094.6205)
:Sending Trackball (ACTION_MOVE): 0:(4.0,3.0)
:Sending Trackball (ACTION_MOVE): 0:(3.0,1.0)
... #其他日志省略
可以修改命令其他参数,保留 -s 5555
可以看到随机指令都一样。如果修改了数量,应该是百分比和前面的指令是一致的。比如把数量从 100 改为 200,前面的百分比和前面的随机指令是一致的。
如何查找应用的 packageName
包名不是指你下载的应用的名称(如 huomaotv.apk ),而是应用的唯一标识packagename
(如 com.huomaotv.mobile )。
那么这里要如何查看应用包名?有如下几种方法(使用以下命令要保证 Android SDK 环境已配置,保证其中 tools、platform-tools 两个目录在环境变量中):
- 该应用已经安装在设备上,通过
adb shell pm list packages
命令查看
adb shell pm list packages -3 # 查看当前设备安装的第三方应用的 packagename
示例:
[C:\~]$ adb shell pm list packages -3
package:io.appium.settings
package:com.huomaotv.mobile
package:com.wude.guild
- 有 apk 安装包的情况下,通过
aapt dump badging <apk路径>
查看包名。
aapt dump badging <apk路径>
示例:
[C:\~]$ aapt dump badging "D:\huomaotv.apk"
package: name='com.huomaotv.mobile' versionCode='79' versionName='3.1.1' platformBuildVersionName=''
sdkVersion:'16'
targetSdkVersion:'23'
uses-permission: name='android.permission.SEND_SMS'
uses-permission: name='android.permission.CHANGE_NETWORK_STATE'
uses-permission: name='android.permission.WRITE_SETTINGS'
... # 其他部分省略
找到其中的package: name='com.huomaotv.mobile'
, com.huomaotv.mobile
就是package name 了。
- 还有一种方法,查看已安装应用的安装目录,Android 中的应用都安装在
/data/data
目录下, 通过adb shell ls
命令查看即可。
adb shell ls /data/data
示例:
[C:\~]$ adb shell ls /data/data
... # 省略部分内容
com.android.wallpapercropper
com.android.webview
com.baidu.yuedu
com.cyanogenmod.filemanager
com.huomaotv.mobile
找到 com.huomaotv.mobile
即可。