这篇我们介绍从Android早期版本的SDK中就自带的一个黑盒自动化测试工具-MonkeyRunner。虽然这个工具名字中也有Monkey,但是MonkeyRunner和Monkey基本没有太大关系。Monkey是运行在Adb shell中的,实际执行在设备本身。而MonkeyRunner则是通过PC端,由Android的API接口来控制设备,进行自动化测试的执行,其主要逻辑是在PC端完成的。
MonkeyRunner支持用Jython(Python脚本的java实现,语法和Python一致)脚本完成自动化测试脚本,可以实现Monkey工具无法提供的逻辑控制、校验等功能。
在Google的官网上有对MonkeyRunner的介绍,并提供了一个脚本示例,实现了应用的安装、启动并对启动后的界面完成截屏操作。
# Imports the monkeyrunner modules used by this program
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
# Connects to the current device, returning a MonkeyDevice object
device = MonkeyRunner.waitForConnection()
# Installs the Android package. Notice that this method returns a boolean, so you can test
# to see if the installation worked.
device.installPackage('myproject/bin/MyApplication.apk')
# sets a variable with the package's internal name
package = 'com.example.android.myapplication'
# sets a variable with the name of an Activity in the package
activity = 'com.example.android.myapplication.MainActivity'
# sets the name of the component to start
runComponent = package + '/' + activity
# Runs the component
device.startActivity(component=runComponent)
# Presses the Menu button
device.press('KEYCODE_MENU', MonkeyDevice.DOWN_AND_UP)
# Takes a screenshot
result = device.takeSnapshot()
# Writes the screenshot to a file
result.writeToFile('myproject/shot1.png','png')
MonkeyRunner主要由三大模块组成:MonkeyRunner、MonkeyDevice、MonkeyImage
- MonkeyRunner -- 包含一些通用的静态方法
- MonkeyDevice -- MonkeyRunner可以控制的设备或模拟器的实体类,可以完成发送UI事件、获取设备信息、安装卸载运行应用等工作
- MonkeyImage -- 图像处理类,可以获取当前设备屏幕并完成基本校验。
MonkeyRunner工具位于Android SDK的tools目录下,通过运行monkeyrunner.bat(Linux下monkeyrunner.sh)即可启动MonkeyRunner的交互界面:
>monkeyrunner
Jython 2.5.3 (2.5:c56500f08d34+, Aug 13 2012, 14:54:35)
[Java HotSpot(TM) 64-Bit Server VM (Oracle Corporation)] on java1.8.0_91
>>>
MonkeyRunner模块的主要方法
返回类型 | 方法 | 作用 |
---|---|---|
void | alert (string message, string title, string okTitle) | 显示一个弹出警告对话框 |
integer | choice (string message, iterable choices, string title) | 显示一个带下拉选择的对话框 |
void | help (string format) | 根据给定的format格式显示MonkeyRunner工具的API说明 |
string | input (string message, string initialValue, string title, string okTitle, string cancelTitle) | 显示说明输入对话框 |
void | sleep (float seconds) | 终止程序运行指定时间 |
MonkeyDevice | waitForConnection (float timeout, string deviceId) | 建立MonkeyRunner和android设备之间的连接 |
这里最常用的是waitforconnection方法,返回一个MonkeyDevice对象,用于建立和设备的连接。
另外help这个方法可以生成一个MonkeyRunner的帮助文档,但大家在执行的时候可能会出错。
这应该是MonkeyRunner工具的一个bug. 因为这个方法需要调用的资源文件没有包含在SDK中,所以要使用这个方法,需要把MonkeyRunner源码中的resource目录拷贝到MonkeyRunner工具所在SDK目录的lib文件夹下,再执行这个方法就可以了
其他的几个方法主要是用于执行交互的对话框操作,比如alert对话框
MonkeyDevice模块的主要方法
返回类型 | 方法 | 作用 |
---|---|---|
void | broadcastIntent (string uri, string action, string data, string mimetype, iterable categories dictionary extras, component component, iterable flags) | 模拟application对象向设备广播 Intent. |
void | drag (tuple start, tuple end, float duration, integer steps) | 触发拖动操作 |
object | getProperty (string key) | 获取给定系统环境变量值,可用的变量清单参见detailed description |
object | getSystemProperty (string key) | 开发者调试方法,用法和adb shell getprop <key>.相同 |
void | installPackage (string path) | 向设备安装应用,如果应用已存在,则替换 |
dictionary | instrument (string className, dictionary args) | 运行指定的 instrumentation组件,组件必须已经保存在设备上了 |
void | press (string name, dictionary type) | 根据给定的keycode执行press操作 |
void | reboot (string into) | 重启设备 |
void | removePackage (string package) | 删除应用,包括缓存和数据 |
object | shell (string cmd) | 执行一个adb shell 命令 |
void | startActivity (string uri, string action, string data, string mimetype, iterable categories dictionary extras, component component, flags) | 通过发送一个Intent来启动指定Activity |
MonkeyImage | takeSnapshot() | 获取整个屏幕界面并返回一个MonkeyImage对象 |
void | touch (integer x, integer y, integer type) | 发送一个点击指定坐标的touch事件 |
void | type (string message) | 发送一组字符输入事件,和使用press方法来输入字符并发送按键事件DOWN_AND_UP效果相同 |
void | wake () | 唤醒设备屏幕 |
这个模块下主要是设备控制的相关操作,也是MonkeyRunner中实际承担自动化操作的主要模块。如启动一个计算器应用
MonkeyImage模块的主要方法
返回类型 | 方法 | 作用 |
---|---|---|
string | convertToBytes (string format) | 将图像转换为二进制字节码内容并以string返回 |
tuple | getRawPixel (integer x, integer y) | 给出指定坐标处像素点的 (a,r,g,b)像素值 |
integer | getRawPixelInt (integer x, integer y) | 给出指定像素点处的整形像素值 |
MonkeyImage | getSubImage (tuple rect) | 根据给定区域生成一个新的MonkeyImage对象 |
boolean | sameAs (MonkeyImage other, float percent) | 比较对象相似度 |
void | writeToFile (string path, string format) | 将MonkeyImage对象保存到指定格式的图像文件中 |
这个模块则是图像保存和比对的功能。这里需要说明的是,MonkeyRunner的sameAs方法,调用的是android源码中的chimpchat类的图像比较方法,精度不高,建议使用的时候尽量先获取subImage来缩小比较范围来提高结果准确性。
关于Android自动化测试工具的详细介绍可参见我的实战课《Android自动化测试实战 Java篇 主流工具 框架 脚本》