如何用MonkeyRunner编写Android自动化测试脚本?

来源:Redis教程作者:小黄人头衔:程序员
导读:本期聚焦于小黄人创作的《如何用MonkeyRunner编写Android自动化测试脚本?》,敬请观看详情。明明只是一个简单的登录操作,回归测试时却要依次点击输入框、输入账号、输入密码、再点登录,重复几十遍之后手都麻了。MonkeyRunner作为Android SDK自带的自动化工具,可以用Jython脚本把这些动作完整录制下来,一键回放。它通过adb通道连接设备或模拟器,提供MonkeyDevice、MonkeyImage、MonkeyRunner三个核心模块,分别负责输入事件、截图对比和脚本控制。本文会从环境搭建入手,逐步拆解按键、触摸、滑动、截图等API的用法,最后给出一个完整的UI冒烟测试脚本,并说明它在多设备兼容性和复杂手势方面的不足。

手动回归测试最让人头疼的,不是测试本身,而是把相同的点击、输入、滑动重复几十遍。MonkeyRunner 正好能把这套动作交给脚本执行。它随 Android SDK 一起发布,位于 tools 目录下,通过 Jython 解释器运行 Python 2 语法的脚本,底层利用 adb 通道向设备或模拟器发送事件。脚本编写门槛不高,只要能看懂 Python 基础语法,就能快速上手。

如何用MonkeyRunner编写Android自动化测试脚本?

MonkeyRunner 的核心由三个类组成:MonkeyRunner 负责脚本入口与设备等待,MonkeyDevice 代表一台已连接的设备或模拟器,MonkeyImage 用来处理截图和图像对比。开发者调用这些 API 即可实现安装应用、启动 Activity、发送按键、模拟触摸、拖拽滑动、执行 shell 命令、保存截图等操作。与 JUnit 或 Espresso 不同,它不关心应用内部 View 层级,只从屏幕坐标和系统事件层面驱动,因此非常适合做冒烟测试和跨应用交互测试。

环境准备与首个连接脚本

使用 MonkeyRunner 前需要安装 JDK 和 Android SDK,并把 SDK 目录下的 tools 和 platform-tools 加入系统环境变量。Windows 下典型路径是 C:\Android\SDK\tools 和 C:\Android\SDK\platform-tools,Linux 或 macOS 则对应解压目录。配置完成后,在命令行输入 monkeyrunner 能看到 Jython 交互提示符,说明环境就绪。MonkeyRunner 脚本文件通常以 .py 结尾,运行时直接执行 monkeyrunner script.py。

连接设备是脚本的第一步。MonkeyRunner.waitForConnection() 会阻塞直到有设备通过 adb 连接,返回一个 MonkeyDevice 对象。如果电脑上同时连接多台设备,可以给 waitForConnection 传入设备序列号参数,避免脚本操作到错误的机器。连接成功后,通过 getProperty 可以读取系统版本、厂商等基础信息,方便在日志中确认目标设备。

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

# 等待设备连接,默认返回第一台可用设备
device = MonkeyRunner.waitForConnection()

# 打印系统版本和设备型号
print "Android version: " + device.getProperty("build.version.release")
print "Device model: " + device.getProperty("build.model")

这段代码只有几行,却能验证整个链路是否通畅。如果控制台输出了版本号和型号,说明 JDK、SDK、adb、MonkeyRunner 四者协作正常。接下来就可以开始注入事件了。需要注意的是,MonkeyRunner 基于 Jython 2.7,语法上遵循 Python 2 规范,print 语句可以不带括号,字符串拼接使用加号也很常见。

核心事件注入:按键、输入与触控

MonkeyDevice 提供了一系列真实设备操作接口。press 方法用于发送系统按键,例如返回键、Home 键、音量键。第一个参数是按键名称,第二个参数是动作类型,DOWN 表示按下,UP 表示抬起,DOWN_AND_UP 表示一次完整点击。type 方法负责向当前焦点输入文本,对已获得焦点的输入框非常有效。touch 方法则直接针对屏幕坐标模拟点击,传入横纵坐标和动作类型即可。

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

device = MonkeyRunner.waitForConnection()

# 启动系统设置应用
device.startActivity(component="com.android.settings/.Settings")
MonkeyRunner.sleep(2)

# 模拟一次返回键点击
device.press('KEYCODE_BACK', MonkeyDevice.DOWN_AND_UP)

# 在焦点输入框中输入文本
device.type("hello monkey")

# 点击屏幕坐标 (200, 400)
device.touch(200, 400, MonkeyDevice.DOWN_AND_UP)

startActivity 方法可以直接拉起任意 Activity,component 参数使用包名和类名组合。相比手动打开应用,这种方式能跳过启动器页面的不确定性。drag 方法用于模拟滑动,可以指定起点、终点、持续时间和步数,常用于翻页或者下拉通知栏。shell 方法则直接执行 adb shell 命令,例如实现屏幕常亮、杀掉进程等系统级操作。

事件注入的本质是把脚本调用翻译成 adb shell input keyevent 或 input tap 等命令,再通过 adb 通道发送给设备端。因此每次操作都存在一定的网络开销,连续大量点击时速度会比 Espresso 这类直接运行在设备内的框架慢。但对于回归测试而言,稳定性远胜于人工操作,速度通常可以接受。实际使用中建议在关键步骤之间调用 MonkeyRunner.sleep() 增加等待,避免页面未加载完成就执行下一步造成误操作。

截图与图像对比在断言中的运用

MonkeyRunner 静态断言能力主要靠截图对比。MonkeyImage 对象通过 device.takeSnapshot() 获得,代表当前屏幕的位图。writeToFile 可以把截图保存到本地,路径需要写绝对路径,Windows 下注意反斜杠转义。sameAs 方法用于比较两张图片的相似度,第二个参数是相似度阈值,范围 0 到 1,1 表示完全一致。当界面发生细微变化时,可以把阈值适当调低,比如 0.9 或 0.85。

# 截图并保存到本地
image = device.takeSnapshot()
image.writeToFile("C:\\monkey\\screen.png", "png")

# 抬起屏幕后再次截图,比较是否发生变化
image1 = device.takeSnapshot()
MonkeyRunner.sleep(1)
device.press('KEYCODE_HOME', MonkeyDevice.DOWN_AND_UP)
MonkeyRunner.sleep(1)
image2 = device.takeSnapshot()

if image1.sameAs(image2, 0.9):
    print "画面未发生明显变化"
else:
    print "检测到界面切换"

截图对比适合验证页面跳转、弹窗消失、按钮状态改变等场景。不过它只比较像素级相似度,无法判断具体文字内容是否正确。如果被测界面中动态元素过多,例如时间栏、电量图标频繁刷新,很容易导致误报。此时可以利用 getSubImage 截取屏幕上相对稳定的子区域,再对子图进行对比,从而避开动态区域的干扰。

综合脚本实战与局限性分析

下面把前面的知识点串联起来,完成一个简单的 UI 冒烟测试脚本:启动设置应用,向上滑动列表,点击第一个可点击项,最后截图保存并输出完成信息。这个脚本没有断言,主要用于演示流程控制。实际项目中可以在关键步骤后加入截图和 sameAs 校验,形成完整的自动化测试闭环。

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

device = MonkeyRunner.waitForConnection()

# 启动设置
device.startActivity(component="com.android.settings/.Settings")
MonkeyRunner.sleep(3)

# 从屏幕下方往上滑动,模拟翻动设置列表
device.drag((300, 900), (300, 300), 0.3, 5)
MonkeyRunner.sleep(1)

# 点击屏幕中部一个列表项
device.touch(300, 500, MonkeyDevice.DOWN_AND_UP)
MonkeyRunner.sleep(2)

# 截图保存
shot = device.takeSnapshot()
shot.writeToFile("C:\\monkey\\smoke_test.png", "png")
print "smoke test finished"

MonkeyRunner 的短板同样明显。它依赖 Jython 2.7,而 Python 2 已经停止维护,新语法和新库无法使用。事件注入只支持坐标和按键,难以处理复杂手势,比如双指缩放。它也不能直接获取 View 树或控件属性,无法实施基于语义的定位与断言。在多设备并行方面,MonkeyRunner 只能一次连接一台设备,若要在多台机器上并发执行,需要自行管理多进程。

所以 MonkeyRunner 更适合作为补充工具,在简单冒烟测试、跨应用操作、安装卸载冒烟等场景中保持轻量高效。如果项目需要长期维护,建议同时评估 Appium、UI Automator 或 Espresso。Appium 支持 WebDriver 协议和多种语言,UI Automator 能获取控件信息,Espresso 则在单应用内提供极快的执行速度。把 MonkeyRunner 定位为快速验证和临时调试工具,往往比强行用它搭建完整测试体系更加合理。

MonkeyRunnerAndroid自动化测试Jython修改时间:2026-10-02 23:09:21

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/1002/64856.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。