本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:MonkeyRunner是Android SDK中的自动化测试工具,支持通过Python脚本控制设备或模拟器,执行如点击、滑动、文本输入、截图等操作。适用于应用自动化测试及批量任务处理。本资源包包含多个示例脚本,如录制回放、帮助文档生成、设备控制等,帮助开发者快速掌握MonkeyRunner的使用方法与核心API,提升测试效率与自动化能力。
monkeyrunner

1. MonkeyRunner简介与安装配置

MonkeyRunner是Android SDK提供的一个基于Python的自动化测试工具,专为Android平台设计,支持对设备进行功能测试、回归测试和UI行为模拟。它通过Java服务器与Android设备通信,提供MonkeyDevice、MonkeyImage等核心类,实现设备控制、图像识别和事件模拟等功能。

要使用MonkeyRunner,首先需配置Java环境与Android SDK,并将 tools 和 platform-tools 路径加入系统环境变量。随后,安装Python 2.7(官方推荐版本),并确保可执行 monkeyrunner 命令。最后通过USB调试模式连接Android设备,使用 adb devices 确认设备识别状态,即可开始编写测试脚本。

本章将为读者奠定MonkeyRunner的使用基础,为后续章节的设备操作、图像识别与自动化测试流程整合做好准备。

2. MonkeyDevice类操作详解

MonkeyDevice类是MonkeyRunner中用于与Android设备交互的核心类,提供了丰富的API来执行设备操作,如启动应用、发送事件、获取设备信息等。掌握MonkeyDevice的使用,是编写高效自动化测试脚本的关键。本章将从基础操作、事件模拟到异常处理与设备管理,系统讲解MonkeyDevice的各类方法及其使用技巧。

2.1 MonkeyDevice的基本操作

MonkeyDevice的基本操作包括设备连接、启动与关闭应用、获取设备信息等,是自动化脚本执行的起点。

2.1.1 连接设备与获取设备实例

在使用MonkeyRunner进行测试之前,必须确保设备已连接到计算机并处于可调试状态。通过 MonkeyRunner.waitForConnection() 方法可以获取设备实例。

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

# 等待设备连接,最长等待时间10秒
device = MonkeyRunner.waitForConnection(10)

if device:
    print("设备连接成功")
else:
    print("设备连接失败")

代码逐行解读:

  • 第1行:导入MonkeyRunner和MonkeyDevice模块。
  • 第4行:调用 waitForConnection() 方法等待设备连接,参数 10 表示最长等待时间为10秒。
  • 第6行:判断是否成功获取设备实例,若成功则输出“设备连接成功”。

设备连接方式:

连接方式 说明
USB连接 最常用,需启用USB调试模式
Wi-Fi连接 需先通过USB连接,再切换到TCP/IP模式
模拟器连接 通过adb自动识别模拟器

提示 :可通过 adb devices 命令查看当前连接的设备列表。

2.1.2 启动和关闭应用

获取设备实例后,可以使用 startActivity() 和 press() 方法启动应用,使用 shell() 方法执行adb命令关闭应用。

# 启动应用
device.startActivity(component="com.example.app/.MainActivity")

# 延迟2秒
MonkeyRunner.sleep(2)

# 关闭应用(通过adb shell am命令)
device.shell("am force-stop com.example.app")

代码说明:

  • startActivity() 用于启动指定包名和Activity的应用。
  • MonkeyRunner.sleep(2) 表示等待2秒,确保应用启动完成。
  • shell() 方法执行adb命令, am force-stop 用于强制停止应用。

启动方式对比:

启动方式 方法 说明
startActivity device.startActivity() 启动指定组件
shell(am start) device.shell("am start ...") 更灵活,可传递Intent参数

2.1.3 获取设备信息与状态

MonkeyDevice提供多种方法获取设备信息,如型号、系统版本、屏幕分辨率等。

# 获取设备属性
device_prop = device.getProperty('build.model')
print(f"设备型号: {device_prop}")

# 获取屏幕截图
snapshot = device.takeSnapshot()
snapshot.writeToFile('screen.png', 'png')

# 获取设备状态(如充电、熄屏等)
status = device.shell("dumpsys power | grep 'mPowerState='")
print(f"设备电源状态: {status}")

输出示例:

设备型号: Pixel 5
设备电源状态: mPowerState=0x1

常用设备信息获取方式:

信息类型 方法/命令 说明
设备型号 device.getProperty('build.model') 获取设备型号
Android版本 device.getProperty('build.version.release') 获取系统版本
屏幕截图 device.takeSnapshot() 获取当前屏幕图像
电源状态 device.shell("dumpsys power") 查看电源管理状态

2.2 MonkeyDevice的事件模拟

事件模拟是MonkeyRunner的核心功能之一,支持点击、滑动、输入、键盘事件等操作,能够模拟用户行为进行自动化测试。

2.2.1 模拟点击、滑动、输入等事件

MonkeyDevice提供了 touch() 、 drag() 、 type() 等方法来模拟用户操作。

# 模拟点击坐标 (500, 1000)
device.touch(500, 1000, MonkeyDevice.DOWN_AND_UP)

# 模拟从(200, 1500)滑动到(800, 1500)
device.drag((200, 1500), (800, 1500), 0.5, 10)

# 模拟输入文本
device.type("Hello, MonkeyRunner!")

事件说明:

  • touch(x, y, type) :模拟点击事件, DOWN_AND_UP 表示按下并释放。
  • drag(start, end, duration, steps) :模拟滑动, duration 为滑动总时间(秒), steps 为分段数。
  • type(text) :模拟键盘输入,逐字符输入。

2.2.2 多点触控与键盘事件处理

MonkeyDevice支持多点触控和键盘事件,通过 press() 和 keyEvent() 方法实现。

# 模拟按下Home键
device.press("KEYCODE_HOME", MonkeyDevice.DOWN_AND_UP)

# 模拟多点触控(双指放大)
device.touch(300, 1000, MonkeyDevice.DOWN)
device.touch(700, 1000, MonkeyDevice.DOWN)
MonkeyRunner.sleep(0.5)
device.touch(300, 1000, MonkeyDevice.UP)
device.touch(700, 1000, MonkeyDevice.UP)

键盘事件对照表:

按键名称 KeyCode 说明
Home KEYCODE_HOME 主页键
Back KEYCODE_BACK 返回键
Menu KEYCODE_MENU 菜单键
Power KEYCODE_POWER 电源键

2.2.3 事件延迟与执行顺序控制

合理控制事件之间的延迟可以提高脚本的稳定性。MonkeyRunner提供了 sleep() 方法用于控制延迟。

# 顺序执行多个事件
device.touch(100, 500, MonkeyDevice.DOWN_AND_UP)
MonkeyRunner.sleep(1)  # 延迟1秒
device.touch(200, 500, MonkeyDevice.DOWN_AND_UP)
MonkeyRunner.sleep(0.5)
device.touch(300, 500, MonkeyDevice.DOWN_AND_UP)

事件执行流程图:

graph TD
    A[开始] --> B[点击(100,500)]
    B --> C[延迟1秒]
    C --> D[点击(200,500)]
    D --> E[延迟0.5秒]
    E --> F[点击(300,500)]
    F --> G[结束]

2.3 MonkeyDevice的异常处理与设备管理

在实际测试中,可能会遇到设备连接中断、操作失败等问题,因此需要对异常进行捕获和处理。

2.3.1 常见连接与操作错误处理

常见的错误包括设备未连接、操作超时、命令执行失败等。可以通过 try-except 结构进行异常捕获。

try:
    device = MonkeyRunner.waitForConnection(5)
    if not device:
        raise Exception("设备连接失败")

    device.touch(1000, 2000, MonkeyDevice.DOWN_AND_UP)
except Exception as e:
    print(f"发生异常: {e}")

常见异常类型:

异常类型 触发场景 说明
TimeoutError waitForConnection超时 等待设备连接超时
IOException 设备通信中断 ADB连接异常
RuntimeException 方法调用失败 如无效坐标、命令执行失败

2.3.2 多设备并发操作与切换

当多个设备连接时,可以通过 MonkeyRunner.waitForConnection() 带参数方式选择设备。

# 获取指定序列号的设备
device1 = MonkeyRunner.waitForConnection(5, "emulator-5554")
device2 = MonkeyRunner.waitForConnection(5, "emulator-5556")

# 分别执行操作
device1.touch(500, 1000, MonkeyDevice.DOWN_AND_UP)
device2.touch(500, 1000, MonkeyDevice.DOWN_AND_UP)

设备切换流程图:

graph LR
    A[开始]
    A --> B[等待设备1连接]
    B --> C[等待设备2连接]
    C --> D[设备1点击操作]
    C --> E[设备2点击操作]
    D --> F[结束]
    E --> F

2.3.3 脚本中断与恢复机制

脚本执行过程中可能会因异常或用户中断而终止,为了保证设备状态可恢复,建议加入清理逻辑。

import sys

try:
    device = MonkeyRunner.waitForConnection(10)
    print("开始执行操作...")
    device.touch(500, 1000, MonkeyDevice.DOWN_AND_UP)
except KeyboardInterrupt:
    print("检测到中断信号,执行清理操作")
    device.shell("am force-stop com.example.app")
    sys.exit(0)

脚本中断恢复策略:

情况 恢复方式 说明
异常退出 try-except捕获 可记录日志、清理资源
用户中断 KeyboardInterrupt 可执行设备清理操作
自动重启 结合外部脚本 通过shell脚本实现重试机制

本章详细讲解了MonkeyDevice类的核心操作,包括设备连接、应用控制、事件模拟、异常处理等。通过本章内容,读者应能够熟练使用MonkeyDevice编写稳定、高效的自动化测试脚本,为后续章节中更复杂的测试流程打下坚实基础。

3. MonkeyImage图像识别与截图比对

MonkeyImage类是MonkeyRunner工具链中用于处理图像数据的核心组件。它不仅可以实现设备界面的截图操作,还能进行图像的像素级访问、裁剪、缩放和比对,为自动化测试提供了直观的界面验证手段。在实际测试过程中,图像识别技术常用于判断UI元素是否加载成功、验证界面状态是否符合预期、检测界面渲染异常等场景。本章将从基础操作入手,深入解析图像比对的实现原理,并结合实际测试案例展示其应用场景。

3.1 MonkeyImage的基本操作

MonkeyImage类提供了丰富的图像处理功能,包括截图、显示、裁剪、缩放和像素访问等操作。这些功能为自动化测试脚本的编写提供了强有力的支持,特别是在需要验证UI状态的场景中尤为关键。

3.1.1 截图保存与图像显示

在MonkeyRunner中,可以通过MonkeyDevice对象获取当前设备屏幕的截图,返回一个MonkeyImage对象。以下是截图保存的基本示例:

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

# 连接设备
device = MonkeyRunner.waitForConnection()

# 获取当前屏幕截图
image = device.takeSnapshot()

# 保存截图到本地
image.writeToFile('/tmp/screenshot.png', 'png')

# 显示图像(仅在支持的环境中有效)
image.writeToFile('/tmp/screenshot.png', 'png')

代码逻辑分析:

  • MonkeyRunner.waitForConnection() :等待设备连接,返回一个MonkeyDevice对象。
  • device.takeSnapshot() :获取当前设备屏幕的截图,返回MonkeyImage对象。
  • writeToFile() :将图像保存为指定格式的文件,第一个参数是文件路径,第二个是图像格式,如 png 或 jpg 。

参数说明:
- file :图像保存路径,必须为字符串。
- format :图像格式,通常使用 png ,因为它支持透明通道,图像质量高。

3.1.2 图像裁剪与缩放处理

MonkeyImage类支持对图像进行裁剪和缩放操作,适用于仅需比对界面某一部分的场景。例如,我们只关心某个按钮区域是否正确显示。

# 获取截图
image = device.takeSnapshot()

# 裁剪图像(x, y, width, height)
cropped_image = image.getSubImage((100, 200, 300, 400))

# 缩放图像(宽度, 高度)
resized_image = cropped_image.resize((150, 200), 1)

# 保存裁剪后的图像
cropped_image.writeToFile('/tmp/cropped.png', 'png')
resized_image.writeToFile('/tmp/resized.png', 'png')

代码逻辑分析:

  • getSubImage() :从原始图像中裁剪出指定区域。参数是一个四元组 (x, y, width, height) ,表示从坐标 (x, y) 开始,裁剪宽度为 width、高度为 height 的矩形区域。
  • resize() :对图像进行缩放,第一个参数是目标尺寸 (width, height) ,第二个参数是缩放质量(通常为1)。

参数说明:
- x/y :裁剪区域左上角坐标。
- width/height :裁剪区域或缩放目标的宽高。
- quality :缩放质量,1表示最优。

3.1.3 图像像素级别的访问

MonkeyImage支持对图像中任意像素点的颜色值进行访问,这在某些图像比对场景中非常有用,例如判断某个按钮的颜色是否发生变化。

# 获取截图
image = device.takeSnapshot()

# 获取某一点的像素颜色值(x, y)
color = image.getRawPixel(100, 200)

# 打印颜色值(ARGB格式)
print(f"Color at (100, 200): {color}")

代码逻辑分析:

  • getRawPixel(x, y) :返回指定坐标的像素颜色值,以整数形式表示 ARGB 值(Alpha, Red, Green, Blue)。
  • 可以将该颜色值与预期值进行比较,用于检测UI状态是否变化。

参数说明:
- x/y :像素点的坐标,必须为整数。
- 返回值是一个整数,表示ARGB颜色值。

3.2 图像比对技术与实现

图像比对是自动化测试中验证界面状态的重要手段。MonkeyImage类提供了基于像素值的图像比对方法,同时也支持通过设置相似度阈值来判断图像是否一致。

3.2.1 基于像素值的图像比对方法

最直接的图像比对方式是逐像素比对两个图像是否完全一致。以下是一个示例:

# 获取两张截图
image1 = device.takeSnapshot()
image2 = device.takeSnapshot()

# 比较图像是否完全一致
if image1.sameAs(image2, 1.0):
    print("Images are identical.")
else:
    print("Images differ.")

代码逻辑分析:

  • sameAs(otherImage, percent) :比较两个图像是否一致。 percent 参数表示相似度阈值,1.0 表示完全一致,0.9 表示允许10%的像素差异。

参数说明:
- otherImage :要比较的另一个MonkeyImage对象。
- percent :相似度阈值,取值范围为0.0~1.0。

3.2.2 使用相似度阈值判断图像一致性

在实际测试中,由于设备分辨率、屏幕刷新率等因素,完全一致的图像比对往往不现实。因此,使用相似度阈值进行判断更为合理。

# 获取截图
image1 = device.takeSnapshot()

# 模拟操作后再次截图
device.touch(500, 800, 'DOWN_AND_UP')
image2 = device.takeSnapshot()

# 设置相似度阈值为0.95(允许5%的差异)
if image1.sameAs(image2, 0.95):
    print("界面状态未发生变化。")
else:
    print("界面状态发生变化,可能存在异常。")

代码逻辑分析:

  • 通过设置 percent=0.95 允许一定比例的像素差异,从而避免因轻微渲染差异导致误判。

参数说明:
- 通常设置为0.95或0.98,适用于大多数界面状态验证。

3.2.3 实现动态截图与比对流程

在自动化测试中,通常需要动态截图并比对,例如判断某个页面是否加载成功。

# 连接设备
device = MonkeyRunner.waitForConnection()

# 启动应用
device.startActivity(component='com.example.app/.MainActivity')

# 等待页面加载
MonkeyRunner.sleep(3)

# 截图并保存为参考图像
reference_image = device.takeSnapshot()
reference_image.writeToFile('/tmp/reference.png', 'png')

# 模拟点击按钮
device.touch(500, 800, 'DOWN_AND_UP')

# 等待界面变化
MonkeyRunner.sleep(2)

# 获取新截图
new_image = device.takeSnapshot()

# 比对
if reference_image.sameAs(new_image, 0.95):
    print("界面未发生变化,可能操作失败。")
else:
    print("界面状态变化成功。")

代码逻辑分析:

  • 首先获取页面加载后的参考图像。
  • 然后模拟操作后再次截图,并与参考图像比对。
  • 如果图像相似度低于阈值,说明界面状态发生变化,操作成功。

流程总结:
- 获取参考图像。
- 执行操作。
- 获取新图像。
- 比对判断状态变化。

3.3 图像识别在测试场景中的应用

图像识别技术在自动化测试中具有广泛的应用价值。它可以帮助测试人员快速验证UI状态、检测异常界面、判断操作是否成功等。

3.3.1 判断特定界面是否加载成功

在自动化测试中,判断应用是否成功跳转到指定界面是一个常见需求。可以通过截图比对来实现:

# 获取当前界面截图
current_image = device.takeSnapshot()

# 读取预存的正确界面截图
expected_image = MonkeyRunner.loadImageFromFile('/tmp/login_success.png')

# 比对
if current_image.sameAs(expected_image, 0.95):
    print("登录成功界面已加载。")
else:
    print("登录界面加载失败或出现异常。")

代码逻辑分析:

  • loadImageFromFile() :从本地加载预存的标准图像。
  • 通过比对当前截图与标准图像判断界面状态。

应用场景:
- 登录成功判断。
- 页面跳转验证。
- 引导页展示检测。

3.3.2 验证UI元素状态变化

在一些交互测试中,我们需要验证某个UI元素的状态是否发生变化,例如按钮是否被点击、图标是否被点亮等。

# 初始截图
before_click = device.takeSnapshot()

# 点击按钮
device.touch(300, 600, 'DOWN_AND_UP')

# 等待状态变化
MonkeyRunner.sleep(1)

# 点击后截图
after_click = device.takeSnapshot()

# 比对
if before_click.sameAs(after_click, 0.95):
    print("按钮状态未变化,点击可能无效。")
else:
    print("按钮状态已变化,操作成功。")

代码逻辑分析:

  • 通过比对点击前后的图像判断UI元素状态是否发生变化。
  • 可用于验证按钮、开关、图标等交互控件。

应用场景:
- 开关状态验证。
- 图标点亮/熄灭检测。
- 按钮点击反馈验证。

3.3.3 自动化测试中的图像识别异常处理

在图像识别过程中,可能会遇到图像模糊、分辨率不一致、设备未连接等问题。合理的异常处理机制可以提升脚本的健壮性。

try:
    # 尝试获取设备连接
    device = MonkeyRunner.waitForConnection(timeout=10)
    if device is None:
        raise Exception("设备连接超时")

    # 获取截图
    image = device.takeSnapshot()
    if image is None:
        raise Exception("截图失败")

    # 比对逻辑
    ...
except Exception as e:
    print(f"发生异常:{str(e)}")

代码逻辑分析:

  • 使用 try-except 结构捕获异常。
  • 对设备连接、截图失败等常见问题进行处理。
  • 提升脚本稳定性。

异常处理建议:
- 检查设备连接状态。
- 设置截图超时时间。
- 对比对失败进行日志记录。

表格:MonkeyImage常用方法汇总

方法名 功能描述 参数说明
takeSnapshot() 获取当前设备屏幕截图 无
getSubImage() 裁剪图像指定区域 (x, y, width, height)
resize() 缩放图像 (width, height), quality
getRawPixel() 获取指定像素点的颜色值 x, y
sameAs() 比较两张图像是否一致 otherImage, percent
writeToFile() 将图像保存到本地文件 file, format

Mermaid流程图:图像识别测试流程图

graph TD
    A[启动应用] --> B[获取参考图像]
    B --> C[执行操作]
    C --> D[获取新图像]
    D --> E{图像比对}
    E -- 相似度高 --> F[界面未变化]
    E -- 相似度低 --> G[界面变化成功]

通过本章的深入讲解,我们可以看到MonkeyImage类在自动化测试中的强大图像处理能力。从基础的截图、裁剪、像素访问,到图像比对和实际测试场景的应用,MonkeyImage为UI验证提供了可靠的技术支持。在下一章中,我们将进一步探讨MonkeyRunner的API调用与事件模拟实战技巧。

4. MonkeyRunner API调用与事件模拟实战

MonkeyRunner作为Android平台上的自动化测试工具,其核心优势在于提供了丰富且灵活的API接口,支持对设备行为、图像识别、事件模拟等多维度的自动化操作。本章将围绕MonkeyRunner API的调用方式、用户行为模拟、脚本编写规范以及实际案例进行系统讲解,帮助读者掌握如何通过MonkeyRunner构建高效、稳定的自动化测试流程。

4.1 MonkeyRunner核心API解析

MonkeyRunner的API体系结构主要由三个核心类组成: MonkeyRunner 、 MonkeyDevice 和 MonkeyImage 。这些类封装了与设备交互、图像处理、事件模拟等关键功能,是编写自动化脚本的基础。

4.1.1 MonkeyRunner类的主要方法

MonkeyRunner 类是脚本的入口类,提供了启动设备连接、等待设备、脚本暂停等功能。其常用方法如下:

方法名 描述
MonkeyRunner.waitForConnection() 等待设备连接
MonkeyRunner.sleep(seconds) 暂停脚本执行指定时间(秒)
MonkeyRunner.alert(message, title, okTitle) 弹出提示对话框
MonkeyRunner.loadImageFromFile(path) 从文件加载图像

示例代码:

from com.android.monkeyrunner import MonkeyRunner

# 等待设备连接
device = MonkeyRunner.waitForConnection()

# 暂停5秒
MonkeyRunner.sleep(5)

# 弹出提示框
MonkeyRunner.alert("测试开始", "提示", "继续")

代码分析:

  • waitForConnection() :用于等待Android设备通过USB连接到PC,成功连接后返回 MonkeyDevice 对象。
  • sleep() :用于控制脚本执行节奏,避免操作过于密集导致设备响应延迟。
  • alert() :调试时用于提示信息,增强脚本交互性。

4.1.2 MonkeyDevice与MonkeyImage的API调用方式

MonkeyDevice 主要用于与设备交互,如启动应用、发送事件等;而 MonkeyImage 则用于图像处理,如截图、像素访问等。

示例:启动应用并截图

# 启动指定应用
device.startActivity(component="com.example.app/.MainActivity")

# 等待3秒确保界面加载完成
MonkeyRunner.sleep(3)

# 截图并保存
result = device.takeSnapshot()
result.writeToFile('/tmp/screenshot.png', 'png')

参数说明:

  • startActivity() :启动目标Activity,参数格式为 包名/全类名 。
  • takeSnapshot() :获取当前设备屏幕截图,返回 MonkeyImage 对象。
  • writeToFile() :将图像保存为指定格式的文件。

4.1.3 自定义函数与模块化封装

为了提升代码的可读性和可维护性,建议将常用操作封装成函数或模块。

def launch_app(device, package, activity):
    """
    启动指定应用
    :param device: MonkeyDevice对象
    :param package: 应用包名
    :param activity: Activity类名
    """
    device.startActivity(component=f"{package}/{activity}")
    MonkeyRunner.sleep(2)

使用方式:

launch_app(device, "com.example.app", ".MainActivity")

优点:

  • 提高代码复用率
  • 增强脚本结构清晰度
  • 方便后期维护和扩展

4.2 用户行为模拟与事件组合

MonkeyRunner支持模拟用户行为,如点击、滑动、输入等,并能模拟系统事件,如设备旋转、来电、断网等。

4.2.1 构建复杂的用户操作序列

自动化测试中,通常需要模拟一系列操作来覆盖完整的用户行为路径。例如登录、提交表单、点击菜单等。

# 点击登录按钮坐标
device.touch(500, 800, 'DOWN_AND_UP')

# 输入用户名
device.type("testuser")

# 点击密码框并输入
device.touch(500, 900, 'DOWN_AND_UP')
device.type("password123")

逻辑分析:

  • touch(x, y, type) :在指定坐标执行点击操作, 'DOWN_AND_UP' 表示按下并释放。
  • type(text) :模拟键盘输入,适用于输入框操作。

4.2.2 模拟设备旋转、来电、断网等系统事件

MonkeyRunner还支持模拟一些系统级事件,有助于测试应用在特定系统状态下的表现。

# 模拟设备旋转为横屏
device.press("KEYCODE_APP_SWITCH", "DOWN_AND_UP")
MonkeyRunner.sleep(1)
device.press("KEYCODE_APP_SWITCH", "DOWN_AND_UP")

# 模拟来电
device.broadcastIntent(action="android.intent.action.PHONE_STATE", 
                      data="tel:1234567890", 
                      category="android.intent.category.DEFAULT")

参数说明:

  • press(key, type) :模拟按键按下事件, KEYCODE_APP_SWITCH 是Android中的切换任务键。
  • broadcastIntent() :发送广播意图,用于模拟系统事件。

4.2.3 实现脚本的逻辑判断与条件执行

在自动化测试中,常常需要根据条件判断是否执行某段代码。虽然MonkeyRunner本身不支持高级逻辑判断,但可以结合Python进行控制。

if is_login_successful(image):
    print("登录成功")
else:
    print("登录失败")

函数实现示例:

def is_login_successful(snapshot):
    expected = MonkeyRunner.loadImageFromFile("/tmp/login_success.png")
    return snapshot.sameAs(expected, 0.9)

流程图:

graph TD
    A[开始测试] --> B{是否登录成功?}
    B -- 是 --> C[输出“登录成功”]
    B -- 否 --> D[输出“登录失败”]

4.3 自动化测试脚本编写规范

良好的脚本编写规范可以提升测试效率、降低维护成本,是构建稳定自动化测试体系的重要基础。

4.3.1 脚本结构设计与模块划分

建议采用模块化结构组织脚本,例如:

test_login.py
utils/
    __init__.py
    device_utils.py
    image_utils.py

device_utils.py 示例:

def connect_device():
    return MonkeyRunner.waitForConnection()

image_utils.py 示例:

def compare_image(snapshot, expected_path, threshold=0.9):
    expected = MonkeyRunner.loadImageFromFile(expected_path)
    return snapshot.sameAs(expected, threshold)

4.3.2 日志记录与调试技巧

MonkeyRunner脚本本身不支持日志输出,但可以通过Python的 print() 或日志模块进行记录。

import logging
logging.basicConfig(level=logging.INFO)

def log_info(message):
    logging.info(f"[TEST] {message}")

使用方式:

log_info("开始执行登录测试")

4.3.3 提高脚本的可维护性与可扩展性

  • 使用常量定义关键参数(如坐标、包名等)
  • 将重复操作封装为函数
  • 使用配置文件管理设备信息、测试数据等
# config.py
APP_PACKAGE = "com.example.app"
APP_ACTIVITY = ".MainActivity"
LOGIN_SUCCESS_IMG = "/tmp/login_success.png"

4.4 典型案例分析与实践

通过实际案例可以更直观地理解MonkeyRunner在自动化测试中的应用。以下将通过登录流程、表单提交、多场景切换三个典型场景进行演示。

4.4.1 登录流程自动化测试

测试目标:

  • 启动应用并进入登录界面
  • 输入用户名和密码
  • 点击登录按钮
  • 验证是否跳转至首页
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

# 启动应用
device = MonkeyRunner.waitForConnection()
device.startActivity(component="com.example.app/.LoginActivity")
MonkeyRunner.sleep(3)

# 输入用户名
device.touch(500, 800, 'DOWN_AND_UP')
device.type("testuser")

# 输入密码
device.touch(500, 900, 'DOWN_AND_UP')
device.type("password123")

# 点击登录
device.touch(500, 1000, 'DOWN_AND_UP')

# 截图验证是否进入首页
snapshot = device.takeSnapshot()
expected = MonkeyRunner.loadImageFromFile("/tmp/home_page.png")
assert snapshot.sameAs(expected, 0.9), "登录失败"

4.4.2 表单提交与错误提示验证

测试目标:

  • 提交空表单
  • 验证是否弹出错误提示
  • 输入合法数据后再次提交
# 提交空表单
device.touch(500, 1100, 'DOWN_AND_UP')

# 截图判断是否显示错误提示
snapshot = device.takeSnapshot()
error_img = MonkeyRunner.loadImageFromFile("/tmp/error_prompt.png")
assert snapshot.sameAs(error_img, 0.9), "错误提示未显示"

# 输入数据并重新提交
device.touch(500, 900, 'DOWN_AND_UP')
device.type("valid_data")
device.touch(500, 1100, 'DOWN_AND_UP')

4.4.3 多场景切换与状态恢复测试

测试目标:

  • 切换应用前后台
  • 模拟来电中断
  • 回到应用验证状态是否保持
# 启动应用
device.startActivity(component="com.example.app/.MainActivity")
MonkeyRunner.sleep(2)

# 模拟来电
device.broadcastIntent(action="android.intent.action.PHONE_STATE", 
                      data="tel:1234567890", 
                      category="android.intent.category.DEFAULT")
MonkeyRunner.sleep(3)

# 返回应用
device.press("KEYCODE_APP_SWITCH", "DOWN_AND_UP")
MonkeyRunner.sleep(1)
device.touch(500, 800, 'DOWN_AND_UP')

# 截图验证界面状态
snapshot = device.takeSnapshot()
expected = MonkeyRunner.loadImageFromFile("/tmp/resumed_state.png")
assert snapshot.sameAs(expected, 0.9), "应用状态未正确恢复"

流程图:

graph TD
    A[启动应用] --> B[模拟来电]
    B --> C[返回应用]
    C --> D[验证状态是否恢复]

通过本章的学习,读者应掌握MonkeyRunner的核心API调用方式、用户行为模拟方法、脚本编写规范以及典型测试案例的实现。这些内容将为后续的脚本录制、测试整合打下坚实基础。

5. MonkeyRunner脚本录制与测试流程整合

MonkeyRunner 提供了脚本录制工具,可以将用户的实际操作记录下来,自动生成可执行的 Python 脚本。这一功能极大地提升了测试脚本的编写效率,尤其适用于界面复杂、操作路径多样的测试场景。本章将从脚本录制工具的使用开始,逐步讲解脚本的优化、执行控制,最后介绍如何将其与主流测试框架及持续集成系统整合,构建完整的自动化测试流程。

5.1 脚本录制工具的使用

MonkeyRunner 提供了两个官方录制工具: monkey_recorder.py 和 monkey_playback.py ,分别用于录制和回放脚本。

5.1.1 monkey_recorder.py的使用方法

monkey_recorder.py 是一个用于记录用户操作并生成 Python 脚本的工具。它会监听设备上的点击、滑动、输入等事件,并将这些操作转换为 MonkeyRunner 的 API 调用。

使用步骤如下:

# 进入 Android SDK 的 tools 目录
cd /path/to/android-sdk/tools

# 启动录制脚本
python monkey_recorder.py

启动后,工具会自动连接设备并开始监听操作。用户可以在设备上进行点击、滑动、输入等操作,这些操作将被记录并输出到控制台。

注意: monkey_recorder.py 默认将操作输出到终端,如果需要保存为脚本文件,可以使用重定向:

python monkey_recorder.py > recorded_script.py

5.1.2 用户操作的录制与脚本生成

在设备上执行一系列操作后, monkey_recorder.py 会生成类似以下格式的脚本:

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

device = MonkeyRunner.waitForConnection()

device.touch(100, 200, 'DOWN_AND_UP')
MonkeyRunner.sleep(1)
device.type('hello world')
MonkeyRunner.sleep(2)
device.press('KEYCODE_MENU', 'DOWN_AND_UP')

该脚本可以直接保存为 .py 文件,并通过以下方式执行:

python recorded_script.py

5.1.3 录制脚本的优化与调整

录制生成的脚本通常需要进行优化,以提高可读性和健壮性。例如:

  • 添加注释 :为每个操作添加说明,便于后续维护。
  • 封装重复操作 :将常用操作封装为函数。
  • 添加异常处理 :防止设备连接失败或操作超时导致脚本中断。

优化示例:

def click_login_button(device):
    # 点击登录按钮
    device.touch(200, 300, 'DOWN_AND_UP')
    MonkeyRunner.sleep(1)

def input_username(device, username):
    # 输入用户名
    device.type(username)
    MonkeyRunner.sleep(1)

# 主流程
device = MonkeyRunner.waitForConnection()
if device is None:
    print("设备连接失败")
    sys.exit(1)

input_username(device, 'test_user')
click_login_button(device)

5.2 脚本回放与执行控制

录制脚本完成后,可以通过 monkey_playback.py 工具进行回放,并结合异常处理机制提升脚本的稳定性。

5.2.1 monkey_playback.py的功能与使用

monkey_playback.py 是一个用于执行录制脚本的工具,支持对录制脚本进行回放:

python monkey_playback.py recorded_script.py

该工具会按录制顺序依次执行脚本中的每一条命令。

5.2.2 脚本回放中的异常处理机制

为了防止脚本在执行过程中因设备断开、界面加载延迟等原因中断,可以添加异常处理逻辑:

try:
    device = MonkeyRunner.waitForConnection(5)
    if device is None:
        raise Exception("设备连接超时")
    # 执行脚本逻辑
    device.touch(100, 200, 'DOWN_AND_UP')
except Exception as e:
    print(f"执行异常: {e}")
    # 可在此添加日志记录或截图操作

5.2.3 控制执行节奏与断点调试

通过 MonkeyRunner.sleep() 可以控制脚本执行节奏,避免因设备响应慢导致的失败:

MonkeyRunner.sleep(2)  # 等待2秒

还可以在关键操作后添加截图功能,用于调试或结果验证:

result = device.takeSnapshot()
result.writeToFile('login_page.png', 'png')

5.3 MonkeyRunner与测试框架的集成

将 MonkeyRunner 脚本与测试框架集成,可以实现测试用例管理、结果分析、报告生成等功能。

5.3.1 结合unittest框架构建测试用例

Python 的 unittest 框架可用于构建结构化的测试用例。以下是将 MonkeyRunner 脚本封装为 unittest 测试用例的示例:

import unittest
from com.android.monkeyrunner import MonkeyRunner

class TestLogin(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.device = MonkeyRunner.waitForConnection()
    def test_login(self):
        self.device.touch(100, 200, 'DOWN_AND_UP')
        MonkeyRunner.sleep(1)
        self.device.type('test_user')
        # 添加断言逻辑

if __name__ == '__main__':
    unittest.main()

5.3.2 测试报告生成与结果分析

可以通过 HTMLTestRunner 或 pytest 插件生成测试报告,便于分析执行结果。例如:

pip install html-testRunner

然后在脚本中导入并使用:

import HTMLTestRunner

runner = HTMLTestRunner.HTMLTestRunner(output='test_reports')
runner.run(unittest.TestLoader().loadTestsFromTestCase(TestLogin))

5.3.3 实现测试用例的批量执行与管理

可以将多个测试用例组织为测试套件(TestSuite),并批量执行:

suite = unittest.TestSuite()
suite.addTest(TestLogin('test_login'))
suite.addTest(TestRegister('test_register'))

runner = unittest.TextTestRunner()
runner.run(suite)

5.4 自动化测试流程整合与持续集成

将 MonkeyRunner 集成到持续集成系统中,可以实现测试流程的自动化运行与结果反馈。

5.4.1 Jenkins与MonkeyRunner的集成方案

Jenkins 是一个流行的持续集成工具。可以创建一个 Jenkins Job,执行以下步骤:

  1. 拉取测试脚本仓库
  2. 安装 Python 依赖
  3. 执行 MonkeyRunner 测试脚本
  4. 生成测试报告
  5. 发送测试结果邮件通知

Jenkins Pipeline 示例:

pipeline {
    agent any
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://your-repo-url.git'
            }
        }
        stage('Run Tests') {
            steps {
                sh 'cd monkeyrunner_tests && python -m unittest discover'
            }
        }
        stage('Generate Report') {
            steps {
                sh 'cd monkeyrunner_tests && python generate_report.py'
            }
        }
    }
}

5.4.2 定时任务与远程执行配置

可以通过 Jenkins 的定时任务功能设置每天固定时间执行测试任务:

triggers {
    cron('0 8 * * *')  // 每天早上8点执行
}

同时,Jenkins 支持远程触发构建,可通过 HTTP 请求远程启动测试流程:

curl -X POST --user user:token http://jenkins-url/job/monkeyrunner-job/build

5.4.3 构建完整的自动化测试流水线

一个完整的自动化测试流水线应包括:

  • 代码提交触发测试
  • 自动化测试脚本执行
  • 测试结果收集与分析
  • 报告生成与通知
  • 失败自动重试机制

通过将 MonkeyRunner 集成到 Jenkins 等 CI/CD 工具中,可以实现从开发到测试再到部署的全链路自动化流程,显著提升测试效率与质量保障能力。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:MonkeyRunner是Android SDK中的自动化测试工具,支持通过Python脚本控制设备或模拟器,执行如点击、滑动、文本输入、截图等操作。适用于应用自动化测试及批量任务处理。本资源包包含多个示例脚本,如录制回放、帮助文档生成、设备控制等,帮助开发者快速掌握MonkeyRunner的使用方法与核心API,提升测试效率与自动化能力。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐