新书上市《深入解析Android 5.0系统》
以下内容节选自本书
Monkeyrunner提供API来让用户开发程序控制Android设备以及模拟器。通过Monkeyrunner,可以写一个Python程序去安装Android应用程序或者测试包,然后运行应用,向它发送模拟输入事件,或者截取它的屏幕,并存储在电脑上。Monkeyrunner工具的主要目的是通过运行单元测试套件在功能和框架级别上测试应用程序和设备,当然也可以将其用于其它目的。
Monkeyrunner并不依赖Monkey。Monkey直接运行在设备或模拟器的adbshell中,产生用户或系统的伪随机事件,但是monkeyrunner工具运行在电脑中,通过API发送特定的命令和事件来控制设备或者模拟器。
1. Monkeyrunner的功能特性如下:
1) 多设备控制:Monkeyrunner的API可以一个或多个测试套件到多台设备或模拟器上。你可以同时连接所有的设备或者一次启动所有的模拟器,然后按顺序依次连接每个设备并且运行一个或多个测试程序。你也可以通过程序启动一个配置好的模拟器,运行一个或多个测试程序,然后关闭模拟器。
2) 功能测试:Monkeyrunner可以为应用自动完成功能测试,但是你需要提供按键的键值或者触摸事件,最后通过保存的截屏图片来了解结果。
3) 回归测试:Monkeyrunner可以在运行某个应用的测试组件时,截取屏幕图片并和以前保存的正确结果的截屏图片相比较,以此测试应用的正确性。
4) 可扩展的自动化:由于Monkeyrunner是一个API工具包,你可以通过Python开发一整套系统来控制Android设备。除了使用Monkeyrunner的API以外,你还可以使用标准Python的功能模块来调用Android的adb工具。
你也可以再Monkeyrunner的API中加入你自己的类。这方面的内容可以参见关于Monkeyrunner的plugin的描述。
Monkeyrunner工具使用的是Jython,它是用Java语言实现的Python,Jython容许Monkeyrunner 的API 很容易的和Android的framework进行交互。使用Jython能够很方便的使用Python的语法来访问任何API的常量,类以及方法。
2. 一个简单的monkeyrunner 的程序例子
在这个例子中,程序将连接到设备,然后创建一个MonkeyDevice对象。通过MonkeyDevice对象,程序将安装一个Android应用并启动它的Activity,然后发送key事件到Activity。最后程序将运行结果进行截屏,并创建一个MonkeyImage对象,通过这个对象,程序将把截取得图片写到一个png文件中。
# 引入 monkeyrunner 模块
fromcom.android.monkeyrunner import MonkeyRunner,MonkeyDevice
# 连接设备,返回结果是一个MonkeyDevice对象
device =MonkeyRunner.waitForConnection()
# 安装一个应用
device.installPackage('myproject/bin/MyApplication.apk')
# 设置包的名称
package ='com.example.android.myapplication'
# 设置Activity的名称
activity ='com.example.android.myapplication.MainActivity'
# 通过包名和Activity的名称组合成组件名称
runComponent = package + '/' +activity
# 运行组件
device.startActivity(component=runComponent)
# 发送按菜单键的事件
device.press('KEYCODE_MENU',MonkeyDevice.DOWN_AND_UP)
# 截取一张屏幕图片
result =device.takeSnapshot()
# 把图片保存到文件
result.writeToFile('myproject/shot1.png','png')
3. MonkeyrunnerAPI简介
Monkeyrunner的API包com.android.monkeyrunner包含有三个模块:
q MonkeyRunner:一个包含了综合功能的类。这个类提供了连接到设备或模拟器的方法,它也提供了为Monkerrunner程序创建应用界面的方法。
q MonkeyDevice:代表一个设备或模拟器。这个类提供安装和卸载应用的方法,启动Activity和发送键盘或触屏消息给应用的方法。你可以使用这个类来运行测试包。
q MonkeyImage:实现截屏功能的类。这个类提供方法完成截屏,转换bitmap格式到其它的格式,比较两幅图片,保存图片到文件等功能。
在一个Python程序中,你能像一个Python模块一样存取类。Monkeyrunner工具并不会自动的包含这三个模块,需要显式的通过语句来import,如下所示:
fromcom.android.monkeyrunner import
是需要引入的类的名称。你可以在一条语句中引入多个模块,模块名称之间用逗号分隔。
4. 运行Monkeyrunner
Monkeyrunner命令的语法是:
monkeyrunner -plugin
-plugin 参数指定了一个包含插件的Jar包。如果需要知道多个插件包,可以多次的使用这个选项。
指定了运行的程序脚本的路径。
指定了程序的参数。
下面的命令可以生成Monkeyrnner API的参考文档:
monkeyrunner help.py
参数的含义是:
的值为text或者html,表示输出文档的格式。
表示输出文件的路径。
5. Monkeyrunner的插件
你能够扩展Monkeyrunner的API通过Java语言编写一个或多个jar文件组成一个插件包。有可以利用这个特性来扩展API通过加入你自己的类或者扩展已经存在的类。你也能使用这个特性来初始化monkeyrunner的环境。
在插件代码中,可以引用和扩展monkeyrunner主要的类:MonkeyDevice,MonkeyImage和MonkeyRunner。
注意插件代码不能访问Android的SDK,不能引入像com.android.app这样的Java包,因为monkeyrunner通过低于系统API的层面和设备或模拟器交互。
插件的jar包中可以指定一个启动类,它将在脚本被执行前实例化。指定启动类,需要加入关键字MonkeyRunnerStartupRunner到jar文件的manifest中,它的值是启动类的名称。下面的片段是在ant的build脚本加入启动类的例子:
jarfile="myplugin" basedir="${build.dir}">
name="MonkeyRunnerStartupRunner"value="com.myapp.myplugin"/>
为了能够在执行时访问monkeyrunner的运行环境,启动类可以实现
com.google.common.base.Predicate。例如:这个类可以在缺省的命名空间中创建一些变量:
packagecom.android.example;
importcom.google.common.base.Predicate;
importorg.python.util.PythonInterpreter;
publicclass Main implements Predicate {
@Override
public boolean apply(PythonInterpreter anInterpreter){
// 创建和初始化一些变量在monkeyrunner的环境中
anInterpreter.set("newtest", "enabled");
anInterpreter.set("use_emulator", 1);
return true;
}
}