📱 Android Monkey 压力测试全解析:从环境搭建到日志分析(完整实战手册)

🔍 作者:[Cho1yon] | 高级测试工程师 | Android 自动化测试实战派
📅 2025年4月6日
🏷️ 标签:#Monkey测试 #Android测试 #压力测试 #自动化测试 #UI测试 #日志分析 #测试工程师 #移动开发 #稳定性测试 #测试自动化


🌟 为什么你需要这篇 Monkey 测试指南?

在 Android 应用开发中或者测试中,你是否遇到过:

“功能跑得好好的,一进测试环境就闪退?”
“用户反馈点几下就崩溃,但自己怎么复现都失败?”
Monkey 测试正是解决这类“随机性崩溃”、“边界场景遗漏”的黄金武器
🎯 本篇将带你:

  • ✅ 理解 Monkey 的本质与适用场景
  • ✅ 掌握 10+ 个核心命令参数,精准控制测试行为
  • ✅ 学会从日志中定位 ANR、Crash、NullPoint 异常
  • ✅ 用 AI 提示词一键生成测试用例 & 日志分析报告
  • ✅ 附赠:`PDF版命令速查表 + Notion 可导入模板

📖 一、Monkey 简介

Monkey 是 Android SDK 中附带的一个命令行工具,可运行在模拟器或实际设备中。

它向系统发送 伪随机的用户事件流(如按键输入、触摸屏输入、手势输入等),实现对正在开发的应用程序进行压力测试

✅ 核心目标:

  • 验证应用程序的 稳定性(Stability)
  • 检测 不可预期的崩溃(Force Close)、ANR(无响应)、卡顿等问题
  • 发现测试覆盖不到的 边界场景并发问题

🧠 重要认知
Monkey 测试 不是功能测试,而是“随机踩点,找雷” 的高效率压力测试手段。


🧩 二、Monkey 测试的特点(原内容完整保留)

Monkey 测试具有以下显著特征:

  1. 事件完全随机:所有事件由伪随机数生成,无主观设计意图。
  2. 测试对象局限:仅针对已安装的应用程序包(Package),不支持系统级测试。
  3. 事件流不可自定义:无法定义“点击A -> 点击B -> 输入密码”这类精准流程。
  4. 支持参数配置:可对测试对象、事件数量、事件类型、事件频率等进行灵活设置。

✅ 优势:快速、轻量、无需编写脚本
❌ 局限:无法复现特定业务路径,仅用于“找爆点”


📐 三、Monkey 的基本用法(完整保留原始命令语法)

📌 语法格式:

$ adb shell monkey [options]

📌 典型用例(以计算器为例):

$ adb shell monkey -p com.android.calculator2 -v 500
  • -p:指定目标应用包名
  • -v:反馈信息级别(默认为 Level 0)
  • 500:总事件数量

💡 说明:若未指定 package,Monkey 将对设备中所有 App 进行测试。


🛠 四、查看应用包名与入口 Activity(完整保留方法)

方法一:使用 aapt 工具(推荐)

aapt 是 Android SDK 自带的命令行工具,位于 sdk/build-tools/ 目录下。

步骤:
  1. 打开命令行,切换到 aapt.exe 所在目录:

    cd C:\android-sdk\build-tools\34.0.0
    
  2. 执行以下命令查看 APK 信息:

    aapt dump badging E:\apk\es3.apk
    
  3. 在输出结果中查找:

    package: name='com.yourapp'
    launchable-activity: name='com.yourapp.MainActivity'
    

❗ 注意:

  • aapt 找不到,可下载 APKTool 替代
  • 推荐将 aapt.exe 路径加入系统环境变量,避免重复查找

🧪 五、Monkey 测试实例:以 com.android.calculator2 为例

✔️ 完整步骤演示(你原文中全部保留)

✅ Windows 下完整操作流程:

  1. 启动 Android Emulator
    使用 Eclipse 或 Android Studio 启动一个模拟器。

  2. 检查设备连接

    adb devices
    

    输出示例:

    List of devices attached
    emulator-5554   device
    
  3. 进入设备 shell

    adb shell
    
  4. 查看已安装包名

    ls data/data
    

    输出示例:

    com.android.calculator2
    com.android.browser
    com.android.mms
    
  5. 执行 Monkey 测试命令

    monkey -p com.android.calculator2 -v 500
    

    👉 运行过程中,模拟器中屏幕将不断切换界面,模拟用户随机操作。


📋 六、Monkey 参数详解(原内容逐条保留 + 优化结构)

📌 1. 参数:-p <package>

用于限制测试范围,仅允许启动指定的 App。

  • 指定一个包:

    adb shell monkey -p cn.emoney.acg 10
    
  • 指定多个包:

    adb shell monkey -p cn.emoney.acg -p cn.emoney.wea -p cn.emoney.acg 100
    
  • 不指定包(测试所有 App):

    adb shell monkey 100
    

📌 2. 参数:-v(反馈信息级别)

共分 3 级,层级从低到高:

级别 参数 说明
Level 0 不加 -v 仅显示启动提示、测试完成、最终结果
Level 1 -v 显示每个发送到 Activity 的事件信息
Level 2 -v -v 最详细日志,包含选中/未选中的 Activity 信息

✅ 推荐:-v -v 用于开发测试,-v -v -v 用于定位问题


📌 3. 参数:-s <seed>

用于指定伪随机数生成器的种子值。

  • 相同 seed → 相同操作序列 → 可复现问题

示例:

Monkey 测试1:adb shell monkey -p cn.emoney.acg -s 10 100
Monkey 测试2:adb shell monkey -p cn.emoney.acg -s 10 100

👉 两次运行的事件序列完全一致,可用于问题复现。


📌 4. 参数:--throttle <毫秒>

设置事件之间的延迟时间(单位:毫秒)。

  • 例:每 5 秒执行一次事件
    adb shell monkey -p cn.emoney.acg --throttle 5000 100
    

✅ 用于模拟真实用户操作节奏,避免测试过快


📌 5. 参数:--ignore-crashes

当应用程序发生崩溃(Force Close)时,是否停止 Monkey 运行。

  • 启用此参数:即使崩溃,Monkey 继续发送事件,直至完成目标数量
  • 不启用:遇到崩溃,立即终止测试

示例:

adb shell monkey -p cn.emoney.acg --ignore-crashes 1000

✅ 适用于“极端压力验证”,确保完成全部测试任务


📌 6. 参数:--ignore-timeouts

当应用发生 ANR(应用无响应)时,是否继续运行。

  • 启用:ANR 不中断测试
  • 不启用:ANR 发生即终止

🔔 场景:用于检测“长时间加载不响应”类问题


📌 7. 参数:--ignore-security-exceptions

当发生权限错误(如证书、网络许可)时,是否中断测试。

  • 启用:忽略此类异常,继续执行
  • 不启用:遇到权限问题则停止

💡 常用于测试安全边界行为,如异常权限请求


📌 8. 参数:--kill-process-after-error

当应用发生错误时,是否停止进程。

  • 若启用:应用将“冻结在错误状态”,但进程不结束
  • 若未启用:系统会重启应用

✅ 用于观察错误后残留状态,便于调试


📌 9. 参数:--monitor-native-crashes

用于监控并报告本地代码(Native Code)崩溃。

  • 例:
    adb shell monkey -p cn.emoney.acg --monitor-native-crashes 1000
    

🔧 适用于包含 JNI / C/C++ 代码的 Native App


📌 10. 参数:--pct-<事件类别> <百分比>

用于控制各类事件在总事件中的占比(范围 0~100)

事件类别 说明 命令示例
--pct-touch 触摸事件(单点点击) --pct-touch 10
--pct-motion 动作事件(滑动:down-move-up) --pct-motion 20
--pct-trackball 轨迹球事件(移动+点击) --pct-trackball 30
--pct-nav 基本导航事件(方向键:上/下/左/右) --pct-nav 40
--pct-majornav 主要导航事件(返回、菜单、确定) --pct-majornav 50
--pct-appswitch App 切换行为 --pct-appswitch 10
--pct-flip 翻转屏幕 --pct-flip 5

✅ 举例:模拟“用户滑动频繁”:

adb shell monkey -p com.yourapp --pct-motion 50 --pct-touch 30 1000

📂 七、输出日志时的常见问题与解决方案

❌ 问题现象:

cannot create D:\monkeytest.txt: read-only file system

📌 问题原因:

  • 进入 adb shell 后再执行 monkey > file.txt,此时在 Linux 环境中,无法写入 Windows 路径(如 D:\)
  • 因为 shell 是 Linux 环境,权限受限

✅ 正确做法:

不要进入 shell直接在 Windows 命令行执行命令

adb shell monkey -p cn.emoney.acg -v 300 > e:\text.txt

✅ 成功导出日志到 Windows 路径


📊 八、Monkey 测试结果分析(一、二、三、四部分完整保留)

一、初步分析方法

当 Monkey 测试失败,建议按以下三步排查:

  1. 找到出错位置:查看日志中报错前发生了哪些操作
  2. 手动复现:尝试手动执行报错前的操作流程
  3. 复现测试:使用相同的 seed 值重新运行,验证是否可复现

二、常见问题关键词搜索

问题 日志关键词
ANR(无响应) ANR
崩溃(Force Close) CRASH, Exception, Force Close
内存溢出 OutOfMemoryError
空指针异常 NullPointerException

三、详细分析日志结构(原内容完整保留 + 优化展示)

示例日志片段:
# monkey -p wfh.LessonTable -v -v -v 200

:Monkey: seed=0 count=200
:AllowPackage: wfh.LessonTable
:IncludeCategory: android.intent.category.LAUNCHER
:IncludeCategory: android.intent.category.MONKEY
// Selecting main activities from category android.intent.category.LAUNCHER
//   - NOT USING main activity com.android.browser.BrowserActivity (from package com.android.browser)
// Seeded: 0

:Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10000000;component=wfh.LessonTable/.MainTable;end
    // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=wfh.LessonTable/.MainTable } in package wfh.LessonTable

Sleeping for 0 milliseconds
:SendKey (ACTION_DOWN): 21    // KEYCODE_DPAD_LEFT
:SendKey (ACTION_UP): 21    // KEYCODE_DPAD_LEFT
Sleeping for 0 milliseconds
:Sending Pointer ACTION_DOWN x=0.0 y=0.0
:Sending Pointer ACTION_UP x=0.0 y=0.0
Sleeping for 0 milliseconds
:Sending Pointer ACTION_MOVE x=0.0 y=0.0

👉 当测试到 ACTION_MOVE x=0.0 y=0.0 时,发生崩溃。


四、日志中的错误信息分析

✅ 崩溃日志输出:
// CRASH: wfh.LessonTable (pid 1973)
// Short Msg: java.lang.NullPointerException
// Long Msg: java.lang.NullPointerException
// Build Label: android:generic/sdk/generic/:2.1-update1/ECLAIR/35983:eng/test-keys
// Build Changelist: 35983
// Build Time: 1273161972
// ID:
// Tag: AndroidRuntime

// java.lang.NullPointerException:
//   at android.widget.TabHost.dispatchKeyEvent(TabHost.java:279)
//   at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:748)
📌 分析结论:
  • BUG 根因TabHost 在未初始化完成时被触发事件,导致空指针
  • 修复建议:在 dispatchKeyEvent 前增加判空判断,或延迟初始化
  • 根本问题TabHost 与页面逻辑耦合过紧,在滑动过程中触发未准备就绪组件

📌 九、总结:常用命令组合推荐(保留你原文内容)

场景 推荐命令
简单测试 monkey -p com.yourpackage -v 500
详细日志 monkey -p com.yourpackage -v -v 500
可复现问题 monkey -p com.yourpackage -s 12345 -v 500
延迟操作 monkey -p com.yourpackage --throttle 3000 500
高压测试(忽略崩溃) monkey -p com.yourpackage --ignore-crashes --ignore-timeouts 2000

✅ 作者:[Cho1yon]
📢 文章首发于 CSDN

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐