Monkey 扰动
入口页只负责入口;随机扰动能力的参数、运行方式和返回结构继续看这里。 重点是看什么时候该用扰动、参数怎么调,以及哪些结果字段能直接拿来验收和排错。
先判断是不是这页的范围
- 你要做随机事件扰动、稳定性压测、异常发现:看这里
- 你要调随机种子、事件节奏、触摸/滑动/导航占比、总事件量:看这里
- 你要做稳定页面点击、输入和等待,不要先从 Monkey 文档开始
- 你只是想知道设备与 UI 执行的整体分层,先去设备与 UI 实战
怎么读这页
- 先看“能力边界和操作方式”,确认它更适合会话式运行,而不是一步到位的短动作
- 再看参数说明,理解默认值适合什么场景、该往哪个方向调
- 最后看底层命令和结果字段,确认怎么留证、怎么复现、怎么排错
这页解决什么问题
- 这组扰动能力到底做了什么
- 启动阶段需要哪些参数
- 默认值适合什么场景
- 返回结果里哪些字段可以直接拿来验收或排错
一句话理解:
- Monkey 负责扰动和异常暴露
- 它不是稳定执行路径的替代品
能力边界和操作方式
当前对外暴露的是一组会话式扰动操作:
monkey_start:提交一次后台随机扰动,并立即返回会话信息monkey_status:查询当前是否仍在运行;没有活跃会话时返回最近一次结果或idlemonkey_wait:在需要最终结果时显式等待当前扰动结束;没有活跃会话时返回最近一次结果或idlemonkey_stop:主动收束当前运行中的扰动;没有活跃会话时返回最近一次结果或idlemonkey_clear:删除最近一次缓存的摘要结果;若当前仍有活跃会话,会提示先停止
默认推荐流程:
- 先调用
monkey_start - 启动后优先调用
monkey_status看进度 - 只有用户明确要求“等它跑完并给最终结果”时,才调用
monkey_wait - 如果用户只想先跑起来,不要在
monkey_start后立刻跟monkey_wait
当前实现默认由 adb monkey 自己拉起目标应用;如果你想从某个稳定页面起跑,应在调用 monkey_start 前自行把应用带到前台。
前台守护默认只记录失焦,不会自动 stop/restart 当前 monkey。
对使用者来说,只需要记住它负责“对目标应用注入随机事件,并持续暴露过程状态与异常摘要”这一件事,不必依赖内部目录结构。
启动前要想清楚什么
如果你只是“先跑起来看看”,其实只需要想清楚下面这些问题:
- 要测哪一个应用
- 是想固定随机序列做复现,还是想多探索一些路径
- 扰动节奏要偏快还是偏慢
- 更偏重点击,还是想要更多滑动、滚动、导航切换
- 这轮是快速冒烟,还是长时间稳定性压测
- 是否需要观察应用有没有跳出前台
- 一旦跳出前台,是只记录、直接停止,还是判为失败
- 会话结束后要不要顺手落盘完整日志
- 多设备场景下,不同设备是否要用不同配置
状态查询、等待、停止和清理属于会话管理动作,本身不需要你再重复描述这些启动意图。
怎么描述你的启动意图
目标应用
这是最基本的输入。
作用:
- Monkey 只会针对这个应用注入随机事件
建议:
- 跑前先确认应用已经安装
- 更稳的链路里,通常先把应用手动带到前台,再开始扰动
随机序列
默认会使用一组固定随机序列,方便复现。
作用:
- 控制这一轮事件分布的大致随机走向
- 相同环境下更容易复现同类问题
建议:
- 做回归时尽量固定
- 做探索时可以换一组随机序列扩大覆盖
扰动节奏
默认节奏偏中等,不是极快压测,也不是接近人工慢速操作。
影响:
- 节奏越快,压力越大
- 节奏越慢,页面有更多时间完成切换和加载
建议:
- 想看高压稳定性就加快
- 想减少误触发和切页抖动就放慢
事件偏好
默认更偏点击,辅以一定比例的滑动和导航类动作。
作用:
- 决定这一轮更像“重点击乱点”,还是“带滚动和切换的探索”
建议:
- 交互密集的页面可以维持较高点击占比
- 列表页、长页面、画廊页可以增加滑动类动作
- 如果只想在当前页面内部做扰动,可以减少导航类动作
事件总量
默认事件量偏大,更适合中长时运行。
影响:
- 事件量越大,测试越久
- 覆盖更广,但也更容易引入长尾问题
建议:
- 快速冒烟先从小事件量开始
- 稳定性压测再逐步拉长
起跑入口
当前实现默认由 adb monkey 自己拉起目标应用。
作用:
- 决定这一轮从哪里开始进入应用
建议:
- 如果你希望从某个稳定页面起跑,应在启动前自行把应用带到那个页面
- 文档里提到的入口信息更像辅助标识,不会替代你手动准备起跑现场
前台守护
默认会观察目标应用是否还在前台,但不会自动接管会话。
作用:
- 帮你知道这一轮是否已经跑偏到别的应用、桌面或系统界面
建议:
- 你关心“这轮是否还在目标应用内”时保持开启
- 你明确接受跳出目标应用继续跑时再关闭
守护敏感度
守护本身有几个可调维度,但你不需要记内部字段名,只要记住这三个意思:
- 检查有多频繁
- 启动初期要不要给应用一段宽限时间
- 要连续偏离几次才算真正跑偏
建议:
- 系统弹窗、通知栏、转场动画较多时,把守护调得宽松一点
- 想更快发现跑偏,就让检查更频繁、阈值更低
跑偏后的处理方式
当前只支持三种自然语义:
- 只记录:记下已经跳出前台,但不自动打断这轮 monkey
- 直接停止:发现跑偏后就收束当前会话
- 记为失败:发现跑偏后把这轮直接判失败
建议:
- 默认先用“只记录”
- 你只关心“不能跑出目标应用”时再用“直接停止”
- 你把“离开前台”本身视为缺陷时再用“记为失败”
日志留存
可以让 monkey 结束后把这一轮 logcat 自动落盘。
适合:
- 你需要留下 crash / ANR / OOM 的完整证据
- 你已经有现成的报告目录,希望顺手把日志汇总进去
注意:
- 当前实现会在给定目录下创建独立子目录,避免并发覆盖
多设备差异化
多设备场景下,可以让不同设备带不同启动意图。
适合:
- 不同设备跑不同应用
- 同一轮里,不同设备使用不同事件量、不同节奏或不同随机序列
底层实际命令
当前实现会拼出类似这样的命令:
adb -s <serial> shell monkey -p <package> \
-s <seed> \
--throttle <throttle_ms> \
--pct-touch <touch> \
--pct-motion <motion> \
--pct-nav <nav> \
--pct-appswitch 0 \
--pct-syskeys 0 \
--ignore-crashes \
--ignore-timeouts \
--ignore-security-exceptions \
-v -v <events>
这里有几个重要点:
--pct-appswitch 0- 不主动做应用切换
--pct-syskeys 0- 不主动打系统键
--ignore-crashes--ignore-timeouts--ignore-security-exceptions- 这些参数保证 Monkey 尽量继续跑,而不是一遇到异常就立即停
所以当前这套更偏:
- 在目标包内做稳定性扰动
- 不把系统级跳转比例开太大
实际执行流程
底层流程不是单纯启动一条命令。
当前实现顺序更接近:
- 清空日志缓存
- 建立日志跟随
- 等待约
0.2s - 启动一段 monkey segment
- 可选启动前台守护轮询
- 并行读取运行输出与日志输出
- 按关键词沉淀摘要、统计和证据片段
- 守护只负责观察或收束当前会话;默认
observe只记录,不接管生命周期 - 全部事件完成或会话被停止后,回收运行进程与日志跟随
如果按会话方式使用,启动动作会先返回;后续再通过状态查询、等待或停止去管理这次运行。
如果启动时传了 saved,当前实现会在结束后把本轮 logcat 导出到该根目录下的独立子目录,便于回放 crash / ANR 证据。
内置关键词监测
当前会监测这几类异常:
crashanroommonkey_abort
内置匹配关键词包括但不限于:
FATAL EXCEPTIONAndroidRuntimeFatal signalSIGSEGVSIGABRTANR inApplication Not RespondingInput dispatching timed outOutOfMemoryErrorFailed to allocateMonkey abortedMonkey finishedEvents injected:
注意:
- 只有命中这些关键词的行,才会进入 tail
- 这能降低噪音,但不等于完整 logcat 全量存档
返回结构
返回里最重要的是 data 字段。当前更适合重点关注:
- 这一轮当前是在运行、已结束、已停止还是已失败
- 当前大约跑了多少事件,还剩多少
- 这轮对应的是哪台设备、哪个目标应用、用了什么随机设置和事件偏好
- 会话标识、开始时间、结束时间和总时长
- 失败原因、调用上下文原因、monkey 退出码
- 关键日志尾部、异常统计、证据片段
- 如果做了日志导出,日志保存到了哪里、总共导出了多少
- 如果发生运行期异常,具体异常文本是什么
这意味着你可以直接拿这些字段做:
- 运行中状态感知
- 时长统计
- 参数回放
- 失败排错
- 结果摘要
其中建议这样理解:
- 终态原因:
- 指这轮 monkey 会话最后是怎么结束的
- 例如正常完成、主动停止、守护收束、离开前台失败
- 调用上下文原因:
- 指你这一次查询、等待、停止或清理时处在什么上下文
- 例如已经在跑、当前没有活跃会话、当前会话正在运行所以不允许清理
不要把两者混用。
怎么理解 ok
这里的 ok 更接近工具运行层是否处于可接受状态,而不是“应用没有任何异常”。
所以要注意:
ok=True不等于“没有 crash / ANR / OOM”- 真正的稳定性证据,要继续看
tail、stats和evidence - 运行中的会话也可能暂时保持
ok=True,这时应优先结合status看阶段
换句话说:
ok更接近“这一轮扰动任务是否正常被提交、运行或收束”tail / stats / evidence更接近“业务稳定性证据”
推荐验收方式
如果你后续把这类扰动纳入回归,建议至少看这几类字段:
statusmonkey_return_codeduration_mstailstats
更稳的判断方式通常是:
- 先确认会话已经结束
- 再检查
tail、stats、evidence里有没有 crash / ANR / OOM 证据 - 必要时结合完整日志导出做额外留证
典型场景
1. 快速冒烟
特点:
- 小事件量
- 固定种子
- 先看有没有明显 crash
2. 稳定性压测
特点:
- 更长事件数
- 可能更小的
throttle_ms - 重点看 ANR、OOM、崩溃 tail
3. 多设备回归
特点:
- 不同设备可以带不同的启动意图
- 统一收集 per-device 结果
实践建议
- 跑前先确认包名正确
- 需要复现问题时固定
seed - 优先按“启动 -> 状态 -> 等待/停止”的会话方式使用,而不是把它当普通短动作
- 不要把
ok=True当成“应用稳定无异常” - 如果要深挖异常,再配合:
- 日志导出
- 截图留证
- 媒体侧证据链
风险和限制
- 当前只暴露一组常用扰动参数,不是完整 adb monkey 全参数面
tail是关键词过滤后的摘要,不是完整日志--pct-appswitch和--pct-syskeys在当前实现里被固定为0- 关键词统计更适合做快速排查,不等于完整问题归因
什么时候优先看这页
- 你要做稳定性扰动
- 你要把 Monkey 接入回归链
- 你在调随机序列、扰动节奏或事件总量
- 你想知道为什么工具显示成功,但应用其实可能已经异常