(一)Monkey简介
Monkey意指猴子,顽皮淘气。所以Monkey测试,顾名思义也就像猴子一样在软件上乱敲按键,猴子什么都不懂,就爱捣乱。
Monkey 是 Android SDK 自带的命令行工具,它通过向系统发送伪随机的用户事件流(如点击、滑动、按键等),对正在运行的应用程序进行压力测试。
Monkey 测试的核心原理基于 Android 系统的事件驱动机制。它生成的事件被发送到系统的事件队列中,然后由系统分发到相应的应用程序。这些随机事件的组合模拟了用户在使用应用时可能进行的各种操作,以此来检测应用在不同操作序列下的表现。
Monkey包括许多选项,它们大致分为四大类:
(1)基本配置选项,如设置尝试的事件数量;
(2)运行约束选项,如设置只对单独的一个包进行测试;
(3)事件类型和频率;
(4)调试选项;
(二)Money原理
在Monkey运行的时候,它生成事件,并把它们发给系统。同时,Monkey还对测试中的系统进行监测,对下列三种情况进行特殊处理(自动停止):
(1)如果限定了Monkey运行在一个或几个特定的包上,那么它会监测试图转到其它包的操作,并对其进行阻止;
(2)如果应用程序崩溃或接收到任何失控异常,Monkey将停止并报错;
(3)如果应用程序产生了应用程序不响应(application not responding)的错误,Monkey将会停止并报错;
按照选定的不同级别的反馈信息,在Monkey中还可以看到其执行过程报告和生成的事件。
(1)Monkey程序由Android系统自带,使用Java语言写成,在Android文件系统中的存放路径是:/system/framework/monkey.jar;
(2)Monkey.jar程序是由一个名为“monkey”的Shell脚本来启动执行,shell脚本在Android文件系统中的存放路径是:/system/bin/monkey;
(3)通过在cmd窗口中执行: adb shell monkey {+命令参数}来进行Monkey测试;
(三)Monkey命令详解
首先我们需要有adb工具,如果没有可以参考 ADB环境配置 ,完成工具安装,熟悉操作环境。
首先,我们需要先知道待测APP的包名,我们可以直接使用adb命令获取包名,先打开进入需要获取包名的APP,再输入命令:
adb shell
dumpsys activity | grep mFocus
基本语法:
adb shell monkey [options] <event-count>
- adb shell:进入设备shell
- monkey:启动Monkey工具
- [options]:配置参数
- <event-count>:事件数量(如10000)
常用参数说明:
参数 | 说明 | 示例 |
-p <包名> | 指定测试的应用包名 | -p com.android.settings |
-s <种子> | 指定随机数种子,便于复现问题 | -s 123 |
--throttle <毫秒> | 设置事件时间间隔 | --throttle 500 |
-v / -vv / -vvv | 设置日志详细程度(最多三级) | -vvv |
--ignore-crashes | 忽略崩溃继续执行 | --ignore-crashes |
--ignore-timeouts | 忽略ABR错误继续执行 | --ignore-timeouts |
--monitor-natvie-crashes | 监控native层崩溃 | --monitor-native-crashes |
--pct-touch <百分比> | 设置触摸事件比例 | --pct-touch 50 |
--pct-motion <百分比> | 设置滑动事件比例 | --pct-touch 30 |
--pct-appswitch <百分比> | 设置应用切换事件比例 | --pct-appswitch 10 |
--pct-rotation <百分比> | 设置屏幕旋转事件比例 | --pct-rotation 5 |
--bugreport | 自动生成bugreport日志 | --bugreport |
> log.txt | 将日志输出到文件 | > /sdcard/monkey_log.txt |
示例命令:
adb shell
monkey -p com.android.settings --throttle 500 -v -v -v --ignore-crashes --ignore-timeouts --pct-touch 50 -pct-motion 30 10000 > /sdcard/monkey_log.txt
含义:对 com.android.settings 执行10000次monkey测试,事件间隔500ms,日志详细,忽略奔溃与超时,触摸事件占50%,滑动事件占30%,并将日志保存为/sdcard/monkey_log.txt文本
注意:adb shell进入后,只能读取到设备的文件路径,例如/sdcard/
如果是adb shell monkey -p com.android.settings -v 10000 > F:\monkey_log.txt 就可以访问本电脑路径,将log直接保存到本电脑
(四)应用场景
1. App稳定性测试(压力测试)
目的: 模拟用户连续操作,验证App是否会崩溃、闪退或无响应
应用场景:
- App发布前的稳定性验证
- 回归测试阶段,确保旧功能未被新版本影响
- 夜间持续运行Monkey,观察长时间运行后的表现
示例命令:
adb shell monkey -p com.exmaple.app --throttle 300 -v -v -v 10000
每300ms发送一次事件,共10000次,记录详细日志
2. Bug复现与定位
目的:通过设置相同的随机种子,复现Monkey触发的异常
应用场景:
- 某次Monkey测试发现崩溃,需复现问题
- 开发修复后,验证是否已解决
示例命令:
adb shell monkey -p com.example.app -s 1752714219455 -v -v -v 10000
使用种子 1752714219455 复现崩溃场景
3. 整机稳定性测试
目的:测试系统级稳定性,包括多App切换、系统按键响应等
应用场景:
- Android系统ROM测试
- 智能硬件整机测试(如电视盒子、车载设备)
示例命令:
adb shell monkey --pct-syskeys 20 --pct-appswitch 30 -v 1000
增加系统按键和App切换事件比例,模拟整机使用场景
4. 安全性与异常处理测试
目的:验证App在权限异常、奔溃、ANR等情况下的处理能力
应用场景:
- 检查是否有未捕获异常
- 验证ANR弹窗是否出现
- 测试App是否能恢复运行
示例命令:
adb shell monkey -p com.example.app --ignore-crashes --ignore-timeouts --monitor-native-crashes -v 10000
即使发生崩溃或者ANR,Monkey继续执行,便于收集更多异常
5. CI自动化集成测试
目的:将Monkey测试集成到持续集成流程,定期执行稳定性验证
应用场景:
- 每次构建后自动执行Monkey测试
- 结合logcat分析异常日志
- 自动生成测试报告
示例命令:
adb shell monkey -p com.example.app --throttle 500 -s 2025 -v 10000 >/sdcard/monkey_log.txt
将日志输出到设备,供后续分析
(五)实战演练
这是我输入monkey -p com.android.settings -v 10000 进行monkey的测试结果
这段日志表明 Monkey 测试异常终止,核心信息是 “系统在执行到第 9647 个事件时崩溃”,具体分析如下:
1. 关键日志解读
Monkey aborted due to error
:Monkey 测试因错误强制终止,未完成预设的 10000 个事件。Events injected: 9647
:实际成功注入 9647 个事件,距离目标 10000 个仅差 353 个。System appears to have crashed at event 9647
:崩溃发生在第 9647 个事件,且可能是系统级崩溃(而非单一应用崩溃)。seed 1752714219455
:测试使用的随机数种子,可用于复现崩溃场景(用相同种子重新执行命令,大概率会在同一事件序列触发崩溃)。elapsed time=267988ms
:测试总耗时约 268 秒(4 分 28 秒),平均每个事件间隔约 27.8 毫秒(若未设置--throttle
,Monkey 会以最快速度发送事件)。
2. 崩溃原因分析
(1)系统级崩溃
- 表现:日志明确提到 “
System appears to have crashed
”,说明不是单一应用(如com.android.settings
)崩溃,而是整个 Android 系统出现严重错误(如进程卡死、内存溢出、内核 panic 等)。- 可能诱因:
- 连续高频率事件导致系统资源耗尽(CPU 100%、内存溢出)。
- 某一事件触发了系统底层漏洞(如框架层代码缺陷、驱动兼容性问题)。
- 设备硬件限制(如低端设备无法承受密集事件压力)。
(2)Monkey 自身限制
- 若测试中涉及跨应用操作(即使指定了
-p
包名,某些系统事件仍可能触发其他应用),可能导致 Monkey 无法处理的异常。- 部分定制 ROM(如厂商修改的系统)对 Monkey 支持不佳,密集事件可能触发系统保护机制(如 watchdog 超时)。
(3)事件序列冲突
- 第 9647 个事件可能是一个特殊操作组合(如连续快速点击 + 旋转屏幕 + 按键),触发了系统未处理的边缘场景(如 UI 线程阻塞、资源竞争死锁)。
3. 复现与排查建议
(1)复现崩溃场景
使用相同种子重新执行测试,确认是否稳定复现:
adb shell monkey -p com.android.settings -s 1752714219455 -v -v 10000
- 若复现,说明是确定性问题(与事件序列强相关)。
- 若偶尔出现,可能是偶发的资源竞争问题。
(2)收集系统崩溃日志
- 测试时同时记录
logcat
系统日志,捕获崩溃瞬间的堆栈信息:adb shell logcat -v time > crash_log.txt # 实时保存日志
- 重点查找关键字:
AndroidRuntime: FATAL EXCEPTION
(应用崩溃)ANR in
(应用无响应)kernel: panic
(内核崩溃)Watchdog: *WATCHDOG*
(系统 watchdog 超时,通常是严重阻塞)
4. 总结
此问题的核心是密集事件触发了系统级崩溃,需通过相同种子复现问题,结合logcat
抓取崩溃堆栈,定位具体是系统资源耗尽、代码漏洞还是硬件限制导致。通过降低事件频率、优化事件类型,可临时规避这个问题