blob: c37e64d645254e0ffb9085869911ef7473a3ae7d [file] [log] [blame]
page.title=monkeyrunner
parent.title=Tools
parent.link=index.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
<li>
<a href="#SampleProgram">A Simple monkeyrunner Program</a>
</li>
<li>
<a href="#APIClasses">The monkeyrunner API</a>
</li>
<li>
<a href="#RunningMonkeyRunner">Running monkeyrunner</a>
</li>
<li>
<a href="#Help">monkeyrunner Built-in Help</a>
</li>
<li>
<a href="#Plugins">Extending monkeyrunner with Plugins</a>
</li>
</ol>
<h2>See Also</h2>
<ol>
<li>
<a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>
</li>
</ol>
</div>
</div>
<p>
The monkeyrunner tool provides an API for writing programs that control an Android device
or emulator from outside of Android code. With monkeyrunner, you can write a Python program
that installs an Android application or test package, runs it, sends keystrokes to it,
takes screenshots of its user interface, and stores screenshots on the workstation. The
monkeyrunner tool is primarily designed to test applications and devices at the
functional/framework level and for running unit test suites, but you are free to use it for
other purposes.
</p>
<p>
The monkeyrunner tool is not related to the
<a href="{@docRoot}tools/help/monkey.html">UI/Application Exerciser Monkey</a>,
also known as the <code>monkey</code> tool. The <code>monkey</code> tool runs in an
<code><a href="{@docRoot}tools/help/adb.html">adb</a></code> shell directly on the
device or emulator and generates pseudo-random streams of user and system events. In comparison,
the monkeyrunner tool controls devices and emulators from a workstation by sending specific
commands and events from an API.
</p>
<p>
The monkeyrunner tool provides these unique features for Android testing:
</p>
<ul>
<li>
Multiple device control: The monkeyrunner API can apply one or more
test suites across multiple devices or emulators. You can physically attach all the devices
or start up all the emulators (or both) at once, connect to each one in turn
programmatically, and then run one or more tests. You can also start up an emulator
configuration programmatically, run one or more tests, and then shut down the emulator.
</li>
<li>
Functional testing: monkeyrunner can run an automated start-to-finish test of an Android
application. You provide input values with keystrokes or touch events, and view the results
as screenshots.
</li>
<li>
Regression testing - monkeyrunner can test application stability by running an application
and comparing its output screenshots to a set of screenshots that are known to be correct.
</li>
<li>
Extensible automation - Since monkeyrunner is an API toolkit, you can develop an entire
system of Python-based modules and programs for controlling Android devices. Besides using
the monkeyrunner API itself, you can use the standard Python
<code><a href="http://docs.python.org/library/os.html">os</a></code> and
<code><a href="http://docs.python.org/library/subprocess.html">subprocess</a></code>
modules to call Android tools such as
<a href="{@docRoot}tools/help/adb.html">Android Debug Bridge</a>.
<p>
You can also add your own classes to the monkeyrunner API. This is described
in more detail in the section
<a href="#Plugins">Extending monkeyrunner with plugins</a>.
</p>
</li>
</ul>
<p>
The monkeyrunner tool uses <a href="http://www.jython.org/">Jython</a>, a
implementation of Python that uses the Java programming language. Jython allows the
monkeyrunner API to interact easily with the Android framework. With Jython you can
use Python syntax to access the constants, classes, and methods of the API.
</p>
<h2 id="SampleProgram">A Simple monkeyrunner Program</h2>
<p>
Here is a simple monkeyrunner program that connects to a device, creating a
<code><a href="{@docRoot}tools/help/MonkeyDevice.html">MonkeyDevice</a></code>
object. Using the <code>MonkeyDevice</code> object, the program installs an Android application
package, runs one of its activities, and sends key events to the activity.
The program then takes a screenshot of the result, creating a
<code><a href="{@docRoot}tools/help/MonkeyImage.html">MonkeyImage</a></code> object.
From this object, the program writes out a <code>.png</code> file containing the screenshot.
</p>
<pre>
# 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')
</pre>
<h2 id="APIClasses">The monkeyrunner API</h2>
<p>
The monkeyrunner API is contained in three modules in the package
<code>com.android.monkeyrunner</code>:
</p>
<ul>
<li>
<code><a href="{@docRoot}tools/help/MonkeyRunner.html">MonkeyRunner</a></code>:
A class of utility methods for monkeyrunner programs. This class provides a method for
connecting monkeyrunner to a device or emulator. It also provides methods for
creating UIs for a monkeyrunner program and for displaying the built-in help.
</li>
<li>
<code><a href="{@docRoot}tools/help/MonkeyDevice.html">MonkeyDevice</a></code>:
Represents a device or emulator. This class provides methods for installing and
uninstalling packages, starting an Activity, and sending keyboard or touch events to an
application. You also use this class to run test packages.
</li>
<li>
<code><a href="{@docRoot}tools/help/MonkeyImage.html">MonkeyImage</a></code>:
Represents a screen capture image. This class provides methods for capturing screens,
converting bitmap images to various formats, comparing two MonkeyImage objects, and
writing an image to a file.
</li>
</ul>
<p>
In a Python program, you access each class as a Python module. The monkeyrunner tool
does not import these modules automatically. To import a module, use the
Python <code>from</code> statement:
</p>
<pre>
from com.android.monkeyrunner import &lt;module&gt;
</pre>
<p>
where <code>&lt;module&gt;</code> is the class name you want to import. You can import more
than one module in the same <code>from</code> statement by separating the module names with
commas.
</p>
<h2 id="RunningMonkeyRunner">Running monkeyrunner</h2>
<p>
You can either run monkeyrunner programs from a file, or enter monkeyrunner statements in
an interactive session. You do both by invoking the <code>monkeyrunner</code> command
which is found in the <code>tools/</code> subdirectory of your SDK directory.
If you provide a filename as an argument, the <code>monkeyrunner</code> command
runs the file's contents as a Python program; otherwise, it starts an interactive session.
</p>
<p>
The syntax of the <code>monkeyrunner</code> command is
</p>
<pre>
monkeyrunner -plugin &lt;plugin_jar&gt; &lt;program_filename&gt; &lt;program_options&gt;
</pre>
<p>
Table 1 explains the flags and arguments.
</p>
<p class="table-caption" id="table1">
<strong>Table 1.</strong> <code>monkeyrunner</code> flags and arguments.</p>
<table>
<tr>
<th>Argument</th>
<th>Description</th>
</tr>
<tr>
<td>
<nobr>
<code>-plugin &lt;plugin_jar&gt;</code>
</nobr>
</td>
<td>
(Optional) Specifies a <code>.jar</code> file containing a plugin for monkeyrunner.
To learn more about monkeyrunner plugins, see
<a href="#Plugins">Extending monkeyrunner with plugins</a>. To specify more than one
file, include the argument multiple times.
</td>
</tr>
<tr>
<td>
<nobr>
<code>&lt;program_filename&gt;</code>
</nobr>
</td>
<td>
If you provide this argument, the <code>monkeyrunner</code> command runs the contents
of the file as a Python program. If the argument is not provided, the command starts an
interactive session.
</td>
</tr>
<tr>
<td>
<code>&lt;program_options&gt;</code>
</td>
<td>
(Optional) Flags and arguments for the program in &lt;program_file&gt;.
</td>
</tr>
</table>
<h2 id="Help">monkeyrunner Built-in Help</h2>
<p>
You can generate an API reference for monkeyrunner by running:
</p>
<pre>
monkeyrunner help.py &lt;format&gt; &lt;outfile&gt;
</pre>
<p>
The arguments are:
</p>
<ul>
<li>
<code>&lt;format&gt;</code> is either <code>text</code> for plain text output
or <code>html</code> for HTML output.
</li>
<li>
<code>&lt;outfile&gt;</code> is a path-qualified name for the output file.
</li>
</ul>
<h2 id="Plugins">Extending monkeyrunner with Plugins</h2>
<p>
You can extend the monkeyrunner API with classes you write in the Java programming language
and build into one or more <code>.jar</code> files. You can use this feature to extend the
monkeyrunner API with your own classes or to extend the existing classes. You can also use this
feature to initialize the monkeyrunner environment.
</p>
<p>
To provide a plugin to monkeyrunner, invoke the <code>monkeyrunner</code> command with the
<code>-plugin &lt;plugin_jar&gt;</code> argument described in
<a href="#table1">table 1</a>.
</p>
<p>
In your plugin code, you can import and extend the the main monkeyrunner classes
<code>MonkeyDevice</code>, <code>MonkeyImage</code>, and <code>MonkeyRunner</code> in
<code>com.android.monkeyrunner</code> (see <a href="#APIClasses">The monkeyrunner API</a>).
</p>
<p>
Note that plugins do not give you access to the Android SDK. You can't import packages
such as <code>com.android.app</code>. This is because monkeyrunner interacts with the
device or emulator below the level of the framework APIs.
</p>
<h3>The plugin startup class</h3>
<p>
The <code>.jar</code> file for a plugin can specify a class that is instantiated before
script processing starts. To specify this class, add the key
<code>MonkeyRunnerStartupRunner</code> to the <code>.jar</code> file's
manifest. The value should be the name of the class to run at startup. The following
snippet shows how you would do this within an <code>ant</code> build script:
</p>
<pre>
&lt;jar jarfile=&quot;myplugin&quot; basedir="&#36;&#123;build.dir&#125;&quot;&gt;
&lt;manifest&gt;
&lt;attribute name=&quot;MonkeyRunnerStartupRunner&quot; value=&quot;com.myapp.myplugin&quot;/&gt;
&lt;/manifest&gt;
&lt;/jar&gt;
</pre>
<p>
To get access to monkeyrunner's runtime environment, the startup class can implement
<code>com.google.common.base.Predicate&lt;PythonInterpreter&gt;</code>. For example, this
class sets up some variables in the default namespace:
</p>
<pre>
package com.android.example;
import com.google.common.base.Predicate;
import org.python.util.PythonInterpreter;
public class Main implements Predicate&lt;PythonInterpreter&gt; {
&#64;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;
}
}
</pre>