APP测试之Monkey压力测试

(一)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,再输入命令:

bash 复制代码
adb shell
dumpsys activity | grep mFocus

基本语法:

adb shell monkey [options] <event-count>

  • adb shell:进入设备shell
  • monkey:启动Monkey工具
  • options\]:配置参数

常用参数说明:

|--------------------------|-----------------|---------------------------|
| 参数 | 说明 | 示例 |
| -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 |

示例命令:

bash 复制代码
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,观察长时间运行后的表现

示例命令:

bash 复制代码
adb shell monkey -p com.exmaple.app --throttle 300 -v -v -v 10000

每300ms发送一次事件,共10000次,记录详细日志

2. Bug复现与定位

目的:通过设置相同的随机种子,复现Monkey触发的异常

应用场景:

  • 某次Monkey测试发现崩溃,需复现问题
  • 开发修复后,验证是否已解决

示例命令:

bash 复制代码
adb shell monkey -p com.example.app -s 1752714219455 -v -v -v 10000

使用种子 1752714219455 复现崩溃场景

3. 整机稳定性测试

目的:测试系统级稳定性,包括多App切换、系统按键响应等

应用场景:

  • Android系统ROM测试
  • 智能硬件整机测试(如电视盒子、车载设备)

示例命令:

bash 复制代码
adb shell monkey --pct-syskeys 20 --pct-appswitch 30 -v 1000

增加系统按键和App切换事件比例,模拟整机使用场景

4. 安全性与异常处理测试

目的:验证App在权限异常、奔溃、ANR等情况下的处理能力

应用场景:

  • 检查是否有未捕获异常
  • 验证ANR弹窗是否出现
  • 测试App是否能恢复运行

示例命令:

bash 复制代码
adb shell monkey -p com.example.app --ignore-crashes --ignore-timeouts --monitor-native-crashes -v 10000

即使发生崩溃或者ANR,Monkey继续执行,便于收集更多异常

5. CI自动化集成测试

目的:将Monkey测试集成到持续集成流程,定期执行稳定性验证

应用场景:

  • 每次构建后自动执行Monkey测试
  • 结合logcat分析异常日志
  • 自动生成测试报告

示例命令:

bash 复制代码
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)复现崩溃场景

使用相同种子重新执行测试,确认是否稳定复现:

bash 复制代码
adb shell monkey -p com.android.settings -s 1752714219455 -v -v 10000
  • 若复现,说明是确定性问题(与事件序列强相关)。
  • 若偶尔出现,可能是偶发的资源竞争问题。

(2)收集系统崩溃日志

  • 测试时同时记录logcat系统日志,捕获崩溃瞬间的堆栈信息:
bash 复制代码
adb shell logcat -v time > crash_log.txt  # 实时保存日志
  • 重点查找关键字:
    • AndroidRuntime: FATAL EXCEPTION(应用崩溃)
    • ANR in(应用无响应)
    • kernel: panic(内核崩溃)
    • Watchdog: *WATCHDOG*(系统 watchdog 超时,通常是严重阻塞)

4. 总结

此问题的核心是密集事件触发了系统级崩溃 ,需通过相同种子复现问题,结合logcat抓取崩溃堆栈,定位具体是系统资源耗尽、代码漏洞还是硬件限制导致。通过降低事件频率、优化事件类型,可临时规避这个问题

相关推荐
liang_jy9 小时前
Android SparseArray
android·源码
liang_jy10 小时前
Activity 启动流程扩展篇(一)—— startActivityInner 任务决策全解析
android·源码
NPE~11 小时前
[App逆向]脱壳实战
android·教程·逆向·android逆向·逆向分析
木易 士心11 小时前
别再只会用 drawCircle 了!一文搞懂 Android Canvas 底层机制
android
AtOR CUES13 小时前
MySQL——表操作及查询
android·mysql·adb
雪碧聊技术13 小时前
什么是压力测试?压力测试的工具有哪些?一文详解
jmeter·压力测试·wrk
怣疯knight14 小时前
安卓App无法增加自定义图片作为图标功能
android
jinanwuhuaguo15 小时前
OpenClaw联邦之心——从孤岛记忆到硅基集体潜意识的拓扑学革命(第二十三篇)
android·人工智能·kotlin·拓扑学·openclaw
Gary Studio17 小时前
安卓HAL C++基础-命名域
android
诸神黄昏EX17 小时前
Android Google XTS
android