传统的 monkeyrunner
工具提供了一个 API,用于编写从 Android 代码外部控制 Android 设备或模拟器的程序。
monkeyrunner
工具主要用于在功能/框架级别测试应用程序和设备,以及运行单元测试套件,但您也可以将其用于其他目的。使用 monkeyrunner
,您可以编写一个 Python 程序,它可以安装 Android 应用程序或测试包,运行它,向它发送按键,截取其用户界面的屏幕截图,并将屏幕截图存储在工作站上。
注意:monkeyrunner
API 未维护。我们建议改用 应用程序爬虫 工具或 UI Automator 测试框架。
monkeyrunner
工具与 UI/应用程序练习猴子(也称为 monkey
工具)无关。monkey
工具直接在设备或模拟器的 adb
shell 中运行,并生成用户和系统事件的伪随机流。相比之下,monkeyrunner
工具通过从 API 发送特定命令和事件来从工作站控制设备和模拟器。
monkeyrunner
工具为 Android 测试提供以下功能
-
多设备控制:
monkeyrunner
API 可以将一个或多个测试套件应用到多个设备或模拟器。您可以一次性物理连接所有设备或启动所有模拟器(或两者),以编程方式依次连接到每个设备,然后运行一个或多个测试。您还可以以编程方式启动模拟器配置,运行一个或多个测试,然后关闭模拟器。 -
功能测试:
monkeyrunner
可以运行 Android 应用程序的自动化端到端测试。您可以使用按键或触摸事件提供输入值,并以屏幕截图形式查看结果。 -
回归测试:
monkeyrunner
通过运行应用程序并将它的输出屏幕截图与一组已知正确的屏幕截图进行比较,可以测试应用程序的稳定性。 -
可扩展的自动化:由于
monkeyrunner
是一个 API 工具包,因此您可以开发一个基于 Python 的模块和程序系统来控制 Android 设备。除了使用monkeyrunner
API 本身之外,您还可以使用标准 Pythonos
和subprocess
模块来调用 Android 工具,例如 Android Debug Bridge。您还可以向
monkeyrunner
API 添加您自己的类。这在 使用插件扩展 monkeyrunner 部分中详细介绍。
monkeyrunner
工具使用 Jython,它是一种使用 Java 编程语言实现的 Python。Jython 使 monkeyrunner
API 能够轻松地与 Android 框架交互。使用 Jython,您可以使用 Python 语法访问 API 的常量、类和方法。
一个简单的 monkeyrunner 程序
这是一个简单的 monkeyrunner
程序,它连接到设备,创建一个 MonkeyDevice
对象。使用 MonkeyDevice
对象,该程序安装 Android 应用程序包,运行其活动之一,并向该活动发送键盘事件。然后,该程序截取结果的屏幕截图,创建一个 MonkeyImage
对象。从该对象中,该程序将包含屏幕截图的 PNG 文件写入磁盘。
# 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 # whether 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 API
monkeyrunner
API 包含在 com.android.monkeyrunner
包中的三个模块中
-
MonkeyRunner
:一个用于monkeyrunner
程序的实用程序方法类。此类提供了一种将monkeyrunner
连接到设备或模拟器的方法。它还提供了用于为monkeyrunner
程序创建 UI 和显示内置帮助的方法。 -
MonkeyDevice
:表示设备或模拟器。此类提供用于安装和卸载包、启动活动以及向应用程序发送键盘或触摸事件的方法。您还可以使用此类运行测试包。 -
MonkeyImage
:表示屏幕截图图像。此类提供用于捕获屏幕、将位图图像转换为各种格式、比较两个MonkeyImage
对象以及将图像写入文件的方法。
在 Python 程序中,您可以将每个类访问为 Python 模块。 monkeyrunner
工具不会自动导入这些模块。要导入模块,请使用 Python from
语句
from com.android.monkeyrunner import <module>
其中 <module>
是要导入的类名。您可以通过用逗号分隔模块名称,在同一 from
语句中导入多个模块。
运行 monkeyrunner
您可以从文件运行 monkeyrunner
程序,也可以在交互式会话中输入 monkeyrunner
语句。 这两种方法都需要调用 monkeyrunner
命令,该命令位于 SDK 目录的 tools/
子目录中。 如果您提供文件名作为参数,monkeyrunner
命令将运行文件的内容作为 Python 程序; 否则,它将启动一个交互式会话。
以下是 monkeyrunner
命令的语法
monkeyrunner -plugin <plugin_jar> <program_filename> <program_options>
表 1 解释了 monkeyrunner
标志和参数。
参数 | 描述 |
---|---|
-plugin <plugin_jar>
|
(可选) 指定一个包含 monkeyrunner 插件的 JAR 文件。 要了解有关 monkeyrunner 插件的更多信息,请参阅 使用插件扩展 monkeyrunner 部分。 若要指定多个文件,请多次包含该参数。 |
<program_filename>
|
如果您提供此参数,monkeyrunner 命令将运行文件的内容作为 Python 程序。 否则,该命令将启动一个交互式会话。 |
<program_options>
|
(可选) <program_file> |
monkeyrunner 内置帮助
您可以通过运行以下命令生成 monkeyrunner
的 API 参考
monkeyrunner help.py <format> <outfile>
参数是
-
<format>
可以是text
(用于纯文本输出)或html
(用于 HTML 输出)。 -
<outfile>
是输出文件的路径限定名称。
使用插件扩展 monkeyrunner
您可以使用在 Java 中编写的类扩展 monkeyrunner
API,并将这些类构建到一个或多个 JAR 文件中。 您可以使用此功能来扩展 monkeyrunner
API,以包含您自己的类,或扩展现有类。 您还可以使用此功能初始化 monkeyrunner
环境。
若要向 monkeyrunner
提供插件,请使用 表 1 中所述的 -plugin <plugin_jar>
参数调用 monkeyrunner
命令。
在您的插件代码中,您可以导入和扩展 com.android.monkeyrunner
中的主要 monkeyrunner
类 MonkeyDevice
、MonkeyImage
和 MonkeyRunner
(请参阅有关 monkeyrunner
API 的部分)。
请注意,插件无法访问 Android SDK。 您无法导入诸如 com.android.app
之类的包。 这是因为 monkeyrunner
在框架 API 的级别以下与设备或模拟器进行交互。
插件启动类
插件的 JAR 文件可以指定一个在脚本处理开始之前实例化的类。 若要指定此类,请将键 MonkeyRunnerStartupRunner
添加到 JAR 文件的清单中。 对于该值,请使用在启动时运行的类的名称。 以下代码段显示了如何在 ant
构建脚本中执行此操作
<jar jarfile="myplugin" basedir="${build.dir}"> <manifest> <attribute name="MonkeyRunnerStartupRunner" value="com.myapp.myplugin"/> </manifest> </jar>
若要访问 monkeyrunner
工具的运行时环境,启动类可以实现 com.google.common.base.Predicate<PythonInterpreter>
。 例如,此类在默认命名空间中设置了一些变量
Kotlin
package com.android.example import com.google.common.base.Predicate import org.python.util.PythonInterpreter class Main: Predicate<PythonInterpreter> { override fun apply(anInterpreter: PythonInterpreter): Boolean { /* * Examples of creating and initializing variables in the monkeyrunner environment's * namespace. During execution, the monkeyrunner program can refer to the variables * "newtest" and "use_emulator" * */ anInterpreter.set("newtest", "enabled") anInterpreter.set("use_emulator", 1) return true } }
Java
package com.android.example; import com.google.common.base.Predicate; import org.python.util.PythonInterpreter; public class Main implements Predicate<PythonInterpreter> { @Override public boolean apply(PythonInterpreter anInterpreter) { /* * Examples of creating and initializing variables in the monkeyrunner environment's * namespace. During execution, the monkeyrunner program can refer to the variables "newtest" * and "use_emulator" * */ anInterpreter.set("newtest", "enabled"); anInterpreter.set("use_emulator", 1); return true; } }