{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/",
  "atlas": "https://www.pystone.net/?node=android-game-automation-adb-monkey-log#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log.md",
  "context": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:android-game-automation-adb-monkey-log",
  "slug": "android-game-automation-adb-monkey-log",
  "title": "Android 游戏自动化测试基础：ADB、Shell、Monkey 与日志",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "Android 游戏自动化测试基础：ADB、Shell、Monkey 与日志",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "2b99f64a860a4980485820a327dff524b8164d042a0103eedf1f4e5abf1a9783",
  "assets": [],
  "headings": [
    {
      "depth": 1,
      "text": "Android 游戏自动化测试基础：ADB、Shell、Monkey 与日志",
      "anchor": "android-游戏自动化测试基础adbshellmonkey-与日志",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#android-%E6%B8%B8%E6%88%8F%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95%E5%9F%BA%E7%A1%80adbshellmonkey-%E4%B8%8E%E6%97%A5%E5%BF%97"
    },
    {
      "depth": 2,
      "text": "1. 为什么先学 ADB",
      "anchor": "1-为什么先学-adb",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#1-%E4%B8%BA%E4%BB%80%E4%B9%88%E5%85%88%E5%AD%A6-adb"
    },
    {
      "depth": 2,
      "text": "2. 设备连接与选择",
      "anchor": "2-设备连接与选择",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#2-%E8%AE%BE%E5%A4%87%E8%BF%9E%E6%8E%A5%E4%B8%8E%E9%80%89%E6%8B%A9"
    },
    {
      "depth": 3,
      "text": "USB 调试",
      "anchor": "usb-调试",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#usb-%E8%B0%83%E8%AF%95"
    },
    {
      "depth": 3,
      "text": "多设备",
      "anchor": "多设备",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#%E5%A4%9A%E8%AE%BE%E5%A4%87"
    },
    {
      "depth": 2,
      "text": "3. 应用安装、启动与数据准备",
      "anchor": "3-应用安装启动与数据准备",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#3-%E5%BA%94%E7%94%A8%E5%AE%89%E8%A3%85%E5%90%AF%E5%8A%A8%E4%B8%8E%E6%95%B0%E6%8D%AE%E5%87%86%E5%A4%87"
    },
    {
      "depth": 2,
      "text": "4. 文件与 Shell",
      "anchor": "4-文件与-shell",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#4-%E6%96%87%E4%BB%B6%E4%B8%8E-shell"
    },
    {
      "depth": 3,
      "text": "常用 Shell 组合",
      "anchor": "常用-shell-组合",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#%E5%B8%B8%E7%94%A8-shell-%E7%BB%84%E5%90%88"
    },
    {
      "depth": 2,
      "text": "5. 输入、截图与录屏",
      "anchor": "5-输入截图与录屏",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#5-%E8%BE%93%E5%85%A5%E6%88%AA%E5%9B%BE%E4%B8%8E%E5%BD%95%E5%B1%8F"
    },
    {
      "depth": 2,
      "text": "6. 性能数据采集",
      "anchor": "6-性能数据采集",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#6-%E6%80%A7%E8%83%BD%E6%95%B0%E6%8D%AE%E9%87%87%E9%9B%86"
    },
    {
      "depth": 3,
      "text": "内存",
      "anchor": "内存",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#%E5%86%85%E5%AD%98"
    },
    {
      "depth": 3,
      "text": "CPU 与进程",
      "anchor": "cpu-与进程",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#cpu-%E4%B8%8E%E8%BF%9B%E7%A8%8B"
    },
    {
      "depth": 3,
      "text": "采集设计",
      "anchor": "采集设计",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#%E9%87%87%E9%9B%86%E8%AE%BE%E8%AE%A1"
    },
    {
      "depth": 2,
      "text": "7. Monkey 稳定性测试",
      "anchor": "7-monkey-稳定性测试",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#7-monkey-%E7%A8%B3%E5%AE%9A%E6%80%A7%E6%B5%8B%E8%AF%95"
    },
    {
      "depth": 2,
      "text": "8. Logcat",
      "anchor": "8-logcat",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#8-logcat"
    },
    {
      "depth": 2,
      "text": "9. 设备信息",
      "anchor": "9-设备信息",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#9-%E8%AE%BE%E5%A4%87%E4%BF%A1%E6%81%AF"
    },
    {
      "depth": 2,
      "text": "10. 从命令走向自动化框架",
      "anchor": "10-从命令走向自动化框架",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#10-%E4%BB%8E%E5%91%BD%E4%BB%A4%E8%B5%B0%E5%90%91%E8%87%AA%E5%8A%A8%E5%8C%96%E6%A1%86%E6%9E%B6"
    },
    {
      "depth": 2,
      "text": "参考资料",
      "anchor": "参考资料",
      "citation": "https://www.pystone.net/notes/android-game-automation-adb-monkey-log/#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:software-engineering-and-quality",
      "title": "软件工程与质量保障",
      "url": "https://www.pystone.net/notes/software-engineering-and-quality/",
      "atlas": "https://www.pystone.net/?node=software-engineering-and-quality#knowledge-atlas",
      "label": "软件工程与质量保障",
      "origin": "explicit",
      "humanReviewed": true,
      "context": "CI-CD与质量保障/CI-CD工具链中的“小熊自动化测试课程”导航项",
      "citation": "https://www.pystone.net/notes/software-engineering-and-quality/#ci-cd%E4%B8%8E%E8%B4%A8%E9%87%8F%E4%BF%9D%E9%9A%9Cci-cd%E5%B7%A5%E5%85%B7%E9%93%BE"
    }
  ],
  "contentMarkdown": "# Android 游戏自动化测试基础：ADB、Shell、Monkey 与日志\n\n> [!note] 课程笔记\n> 本文提炼自侑虎科技高嵘讲授的游戏自动化测试课程（原题“小熊自动化测试课程”，2021-01-06）。已删除课堂过渡语、口语重复、个人路径、示例密码和具体内部应用标识，并按知识主题重组。课程原计划还包括 Python 与 Airtest；本笔记现有材料主要覆盖 ADB 与 Android 命令行基础。\n\n> [!warning] 使用边界\n> 只对自己拥有或明确获授权的设备与应用执行调试、数据清除、输入注入和压力测试。命令会卸载应用、清除数据或产生大量事件，运行前确认包名、设备序列号与测试环境。\n\n## 1. 为什么先学 ADB\n\nADB（Android Debug Bridge）是开发机与 Android 设备之间的调试桥梁。许多 UI 自动化框架会在底层借助 ADB 完成安装、启动、输入、截图、日志和文件传输。理解 ADB 有助于：\n\n- 判断故障发生在设备连接、框架封装还是业务脚本；\n- 把环境准备、数据采集与测试执行拆成可复用步骤；\n- 在没有完整 UI 框架时快速构造诊断脚本。\n\nADB 包含开发机上的客户端、后台 server 和设备上的 `adbd`。应从 Android SDK Platform-Tools 官方渠道取得，不使用来历不明的独立下载站。\n\n## 2. 设备连接与选择\n\n### USB 调试\n\n1. 在测试设备启用开发者选项与 USB 调试。\n2. 使用数据线连接，并在设备上确认主机 RSA 指纹。\n3. 检查状态：\n\n```bash\nadb start-server\nadb devices -l\n```\n\n`unauthorized` 表示设备尚未授权；`offline` 可能需要重连、重启 ADB 或检查驱动。\n\n### 多设备\n\n脚本中不要默认“只有一台设备”，应显式指定序列号：\n\n```bash\nadb -s <serial> shell getprop ro.product.model\n```\n\n网络调试会扩大攻击面，只在隔离测试网络中按 Android 当前官方流程启用，用完关闭并撤销配对。\n\n## 3. 应用安装、启动与数据准备\n\n```bash\nadb -s <serial> install -r <app.apk>\nadb -s <serial> uninstall <package.name>\nadb -s <serial> shell pm list packages\nadb -s <serial> shell pm clear <package.name>\nadb -s <serial> shell am force-stop <package.name>\nadb -s <serial> shell am start -n <package.name>/<activity.name>\n```\n\n- `install -r` 表示保留数据重新安装，但签名、版本和降级规则仍会影响结果。\n- `pm clear` 会删除应用数据，必须在测试环境确认后执行。\n- 启动入口可通过构建配置、包管理器或 `dumpsys package` 核验，不要依赖 `top` 猜包名。\n\n现代 Android 的 Activity 生命周期应以官方文档和应用日志为准；“运行、暂停、停止、销毁”是便于理解的状态概括，不替代 `onCreate`、`onStart`、`onResume` 等真实回调验证。\n\n## 4. 文件与 Shell\n\n```bash\nadb -s <serial> push <local-file> /sdcard/Download/\nadb -s <serial> pull /sdcard/Download/<file> <local-dir>\nadb -s <serial> shell\n```\n\n设备 Shell 权限受 Android 版本、应用沙箱、SELinux 与是否 root 影响。不要把能在工程机上运行的命令假定为所有量产设备都可用。\n\n### 常用 Shell 组合\n\n```bash\ncommand-a | grep 'pattern'\ncommand-a | awk '{print $1}'\nwhile true; do\n  command-a\n  sleep 3\ndone\n```\n\n在 Windows PowerShell、cmd、macOS/Linux Shell 与设备 Shell 之间，管道、引号、变量和文本工具并不完全相同。复杂采集逻辑应明确在哪一层执行，并把脚本纳入版本管理和审查。\n\n## 5. 输入、截图与录屏\n\n```bash\nadb -s <serial> shell input text '<text>'\nadb -s <serial> shell input keyevent <keycode>\nadb -s <serial> shell input tap <x> <y>\nadb -s <serial> shell input swipe <x1> <y1> <x2> <y2> <duration-ms>\n\nadb -s <serial> exec-out screencap -p > screenshot.png\nadb -s <serial> shell screenrecord /sdcard/test.mp4\nadb -s <serial> pull /sdcard/test.mp4 .\n```\n\n坐标脚本容易受分辨率、密度、旋转、系统栏和 UI 改版影响。稳定测试优先使用资源 ID、可访问性节点或游戏框架提供的语义定位；坐标输入适合快速验证和兜底。\n\n不要把解锁密码写入脚本或日志，也不要通过输入注入绕过设备安全策略。\n\n## 6. 性能数据采集\n\n### 内存\n\n```bash\nadb -s <serial> shell dumpsys meminfo <package.name>\n```\n\n记录 PSS 及分类时，同时保存设备、系统、构建、场景和采样时间。一次不回落不能证明泄漏；应按固定步骤多轮采样，并结合对象快照或原生分配工具定位。\n\n### CPU 与进程\n\nAndroid 不同版本的 `top` 参数和 CPU 口径可能不同：\n\n```bash\nadb -s <serial> shell top -b -n 1\nadb -s <serial> shell dumpsys cpuinfo\nadb -s <serial> shell pidof <package.name>\n```\n\n不要用“CPU 数值除以核心数”作为通用换算。某些工具以单核 100% 为上限，某些以整机 100% 为上限；先确认设备版本和命令输出定义。\n\n### 采集设计\n\n1. 测试开始前记录时间戳、版本和设备属性。\n2. 启动被测场景并等待稳定。\n3. 按固定间隔采集原始输出，原始数据不要只保留换算结果。\n4. 对齐操作事件、日志、CPU、内存与帧时间。\n5. 测试结束后归档 seed、脚本、异常截图和退出码。\n\n## 7. Monkey 稳定性测试\n\nMonkey 向应用或系统发送伪随机事件，适合发现崩溃、ANR 和脆弱状态，不等同于可验证业务结果的功能测试。\n\n```bash\nadb -s <serial> shell monkey \\\n  -p <package.name> \\\n  -s 300 \\\n  --throttle 300 \\\n  --monitor-native-crashes \\\n  -v -v \\\n  1000\n```\n\n- `-p` 限制目标包。\n- `-s` 固定伪随机 seed，便于复现相近事件序列。\n- `--throttle` 设置事件间隔。\n- 多个 `-v` 提高日志详细程度。\n- 忽略 crash/timeout 的选项会让测试继续，但不能把错误当作通过；流水线仍应解析并报告异常。\n\n执行前关闭可能伤害数据或产生真实交易的入口，使用专用账号与测试环境。复现失败时保存完整命令、seed、设备状态、日志和应用版本。\n\n## 8. Logcat\n\n```bash\nadb -s <serial> logcat -c\nadb -s <serial> logcat -v threadtime\nadb -s <serial> logcat -d > logcat.txt\nadb -s <serial> logcat --pid=$(adb -s <serial> shell pidof <package.name>)\n```\n\n常见优先级为 Verbose、Debug、Info、Warn、Error、Fatal。缓冲区名称与可见权限随系统版本变化，可按需选择 `main`、`system`、`crash` 等。\n\n日志本身可能包含用户数据、网络参数、Token 与内部地址。公开或上传前必须脱敏，生产应用也不应记录秘密。\n\n## 9. 设备信息\n\n```bash\nadb -s <serial> shell getprop ro.product.model\nadb -s <serial> shell getprop ro.product.brand\nadb -s <serial> shell getprop ro.build.version.release\nadb -s <serial> shell wm size\nadb -s <serial> shell wm density\nadb -s <serial> shell dumpsys battery\nadb -s <serial> shell cat /proc/meminfo\n```\n\nIMEI、Android ID、MAC 等属于设备或个人标识符，权限限制严格，也不应作为普通测试报告的默认字段。仅在具有合法目的和最小必要性时采集，并遵守保存与脱敏要求。\n\n## 10. 从命令走向自动化框架\n\n一条可维护的自动化链路可拆为：\n\n```text\n环境检查 → 安装/清数据 → 启动 → 执行业务动作\n        → 并行采集日志与性能 → 断言 → 清理 → 报告\n```\n\nADB 适合环境与设备层；Python 用于编排、解析和报告；Airtest/Appium 等用于 UI 或游戏交互。框架选择应服从定位稳定性、运行成本和可诊断性，而不是只比较 API 是否“方便”。\n\n## 参考资料\n\n- [Android Developers：Android Debug Bridge](https://developer.android.com/tools/adb)\n- [Android Developers：UI/Application Exerciser Monkey](https://developer.android.com/studio/test/other-testing-tools/monkey)\n- [Android Developers：Logcat command-line tool](https://developer.android.com/tools/logcat)\n"
}
