1page.title=monkeyrunner
2parent.title=Tools
3parent.link=index.html
4@jd:body
5
6<div id="qv-wrapper">
7  <div id="qv">
8  <h2>In this document</h2>
9  <ol>
10    <li>
11        <a href="#SampleProgram">A Simple monkeyrunner Program</a>
12    </li>
13    <li>
14        <a href="#APIClasses">The monkeyrunner API</a>
15    </li>
16    <li>
17        <a href="#RunningMonkeyRunner">Running monkeyrunner</a>
18    </li>
19    <li>
20        <a href="#Help">monkeyrunner Built-in Help</a>
21    </li>
22    <li>
23        <a href="#Plugins">Extending monkeyrunner with Plugins</a>
24    </li>
25  </ol>
26  <h2>See Also</h2>
27      <ol>
28        <li>
29            <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>
30        </li>
31      </ol>
32  </div>
33</div>
34<p>
35    The monkeyrunner tool provides an API for writing programs that control an Android device
36    or emulator from outside of Android code. With monkeyrunner, you can write a Python program
37    that installs an Android application or test package, runs it, sends keystrokes to it,
38    takes screenshots of its user interface, and stores screenshots on the workstation. The
39    monkeyrunner tool is primarily designed to test applications and devices at the
40    functional/framework level and for running unit test suites, but you are free to use it for
41    other purposes.
42</p>
43<p>
44    The monkeyrunner tool is not related to the
45    <a href="{@docRoot}tools/help/monkey.html">UI/Application Exerciser Monkey</a>,
46    also known as the <code>monkey</code> tool. The <code>monkey</code> tool runs in an
47    <code><a href="{@docRoot}tools/help/adb.html">adb</a></code> shell directly on the
48    device or emulator and generates pseudo-random streams of user and system events. In comparison,
49    the monkeyrunner tool controls devices and emulators from a workstation by sending specific
50    commands and events from an API.
51</p>
52<p>
53    The monkeyrunner tool provides these unique features for Android testing:
54</p>
55<ul>
56    <li>
57        Multiple device control: The monkeyrunner API can apply one or more
58        test suites across multiple devices or emulators. You can physically attach all the devices
59        or start up all the emulators (or both) at once, connect to each one in turn
60        programmatically, and then run one or more tests. You can also start up an emulator
61        configuration programmatically, run one or more tests, and then shut down the emulator.
62    </li>
63    <li>
64        Functional testing: monkeyrunner can run an automated start-to-finish test of an Android
65        application. You provide input values with keystrokes or touch events, and view the results
66        as screenshots.
67    </li>
68    <li>
69        Regression testing - monkeyrunner can test application stability by running an application
70        and comparing its output screenshots to a set of screenshots that are known to be correct.
71    </li>
72    <li>
73        Extensible automation - Since monkeyrunner is an API toolkit, you can develop an entire
74        system of Python-based modules and programs for controlling Android devices. Besides using
75        the monkeyrunner API itself, you can use the standard Python
76        <code><a href="http://docs.python.org/library/os.html">os</a></code> and
77        <code><a href="http://docs.python.org/library/subprocess.html">subprocess</a></code>
78        modules to call Android tools such as
79        <a href="{@docRoot}tools/help/adb.html">Android Debug Bridge</a>.
80        <p>
81            You can also add your own classes to the monkeyrunner API. This is described
82            in more detail in the section
83            <a href="#Plugins">Extending monkeyrunner with plugins</a>.
84        </p>
85    </li>
86</ul>
87<p>
88    The monkeyrunner tool uses <a href="http://www.jython.org/">Jython</a>, a
89    implementation of Python that uses the Java programming language. Jython allows the
90    monkeyrunner API to interact easily with the Android framework. With Jython you can
91    use Python syntax to access the constants, classes, and methods of the API.
92</p>
93
94<h2 id="SampleProgram">A Simple monkeyrunner Program</h2>
95<p>
96    Here is a simple monkeyrunner program that connects to a device, creating a
97    <code><a href="{@docRoot}tools/help/MonkeyDevice.html">MonkeyDevice</a></code>
98    object. Using the <code>MonkeyDevice</code> object, the program installs an Android application
99    package, runs one of its activities, and sends key events to the activity.
100    The program then takes a screenshot of the result, creating a
101    <code><a href="{@docRoot}tools/help/MonkeyImage.html">MonkeyImage</a></code> object.
102    From this object, the program writes out a <code>.png</code> file containing the screenshot.
103</p>
104<pre>
105# Imports the monkeyrunner modules used by this program
106from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
107
108# Connects to the current device, returning a MonkeyDevice object
109device = MonkeyRunner.waitForConnection()
110
111# Installs the Android package. Notice that this method returns a boolean, so you can test
112# to see if the installation worked.
113device.installPackage('myproject/bin/MyApplication.apk')
114
115# sets a variable with the package's internal name
116package = 'com.example.android.myapplication'
117
118# sets a variable with the name of an Activity in the package
119activity = 'com.example.android.myapplication.MainActivity'
120
121# sets the name of the component to start
122runComponent = package + '/' + activity
123
124# Runs the component
125device.startActivity(component=runComponent)
126
127# Presses the Menu button
128device.press('KEYCODE_MENU', MonkeyDevice.DOWN_AND_UP)
129
130# Takes a screenshot
131result = device.takeSnapshot()
132
133# Writes the screenshot to a file
134result.writeToFile('myproject/shot1.png','png')
135</pre>
136
137<h2 id="APIClasses">The monkeyrunner API</h2>
138<p>
139    The monkeyrunner API is contained in three modules in the package
140    <code>com.android.monkeyrunner</code>:
141</p>
142<ul>
143    <li>
144        <code><a href="{@docRoot}tools/help/MonkeyRunner.html">MonkeyRunner</a></code>:
145        A class of utility methods for monkeyrunner programs. This class provides a method for
146        connecting monkeyrunner to a device or emulator. It also provides methods for
147        creating UIs for a monkeyrunner program and for displaying the built-in help.
148    </li>
149    <li>
150        <code><a href="{@docRoot}tools/help/MonkeyDevice.html">MonkeyDevice</a></code>:
151        Represents a device or emulator. This class provides methods for installing and
152        uninstalling packages, starting an Activity, and sending keyboard or touch events to an
153        application. You also use this class to run test packages.
154    </li>
155    <li>
156        <code><a href="{@docRoot}tools/help/MonkeyImage.html">MonkeyImage</a></code>:
157        Represents a screen capture image. This class provides methods for capturing screens,
158        converting bitmap images to various formats, comparing two MonkeyImage objects, and
159        writing an image to a file.
160    </li>
161</ul>
162<p>
163    In a Python program, you access each class as a Python module. The monkeyrunner tool
164    does not import these modules automatically. To import a module, use the
165    Python <code>from</code> statement:
166</p>
167<pre>
168from com.android.monkeyrunner import &lt;module&gt;
169</pre>
170<p>
171    where <code>&lt;module&gt;</code> is the class name you want to import. You can import more
172    than one module in the same <code>from</code> statement by separating the module names with
173    commas.
174</p>
175<h2 id="RunningMonkeyRunner">Running monkeyrunner</h2>
176<p>
177    You can either run monkeyrunner programs from a file, or enter monkeyrunner statements in
178    an interactive session. You do both by invoking the <code>monkeyrunner</code> command
179    which is found in the <code>tools/</code> subdirectory of your SDK directory.
180    If you provide a filename as an argument, the <code>monkeyrunner</code> command
181    runs the file's contents as a Python program; otherwise, it starts an interactive session.
182</p>
183<p>
184    The syntax of the <code>monkeyrunner</code> command is
185</p>
186<pre>
187monkeyrunner -plugin &lt;plugin_jar&gt; &lt;program_filename&gt; &lt;program_options&gt;
188</pre>
189<p>
190Table 1 explains the flags and arguments.
191</p>
192<p class="table-caption" id="table1">
193  <strong>Table 1.</strong> <code>monkeyrunner</code> flags and arguments.</p>
194
195<table>
196    <tr>
197        <th>Argument</th>
198        <th>Description</th>
199    </tr>
200    <tr>
201        <td>
202            <nobr>
203                <code>-plugin &lt;plugin_jar&gt;</code>
204            </nobr>
205        </td>
206        <td>
207            (Optional) Specifies a <code>.jar</code> file containing a plugin for monkeyrunner.
208            To learn more about monkeyrunner plugins, see
209            <a href="#Plugins">Extending monkeyrunner with plugins</a>. To specify more than one
210            file, include the argument multiple times.
211        </td>
212    </tr>
213    <tr>
214        <td>
215            <nobr>
216                <code>&lt;program_filename&gt;</code>
217            </nobr>
218        </td>
219        <td>
220            If you provide this argument, the <code>monkeyrunner</code> command runs the contents
221            of the file as a Python program. If the argument is not provided, the command starts an
222            interactive session.
223        </td>
224    </tr>
225    <tr>
226        <td>
227            <code>&lt;program_options&gt;</code>
228        </td>
229        <td>
230            (Optional) Flags and arguments for the program in &lt;program_file&gt;.
231        </td>
232    </tr>
233</table>
234<h2 id="Help">monkeyrunner Built-in Help</h2>
235<p>
236    You can generate an API reference for monkeyrunner by running:
237</p>
238<pre>
239monkeyrunner help.py &lt;format&gt; &lt;outfile&gt;
240</pre>
241<p>
242The arguments are:
243</p>
244    <ul>
245        <li>
246            <code>&lt;format&gt;</code> is either <code>text</code> for plain text output
247            or <code>html</code> for HTML output.
248        </li>
249        <li>
250            <code>&lt;outfile&gt;</code> is a path-qualified name for the output file.
251        </li>
252    </ul>
253<h2 id="Plugins">Extending monkeyrunner with Plugins</h2>
254<p>
255    You can extend the monkeyrunner API with classes you write in the Java programming language
256    and build into one or more <code>.jar</code> files. You can use this feature to extend the
257    monkeyrunner API with your own classes or to extend the existing classes. You can also use this
258    feature to initialize the monkeyrunner environment.
259</p>
260<p>
261    To provide a plugin to monkeyrunner, invoke the <code>monkeyrunner</code> command with the
262    <code>-plugin &lt;plugin_jar&gt;</code> argument described in
263    <a href="#table1">table 1</a>.
264</p>
265<p>
266    In your plugin code, you can import and extend the the main monkeyrunner classes
267    <code>MonkeyDevice</code>, <code>MonkeyImage</code>, and <code>MonkeyRunner</code> in
268    <code>com.android.monkeyrunner</code> (see <a href="#APIClasses">The monkeyrunner API</a>).
269</p>
270<p>
271    Note that plugins do not give you access to the Android SDK. You can't import packages
272    such as <code>com.android.app</code>. This is because monkeyrunner interacts with the
273    device or emulator below the level of the framework APIs.
274</p>
275<h3>The plugin startup class</h3>
276<p>
277    The <code>.jar</code> file for a plugin can specify a class that is instantiated before
278    script processing starts. To specify this class, add the key
279    <code>MonkeyRunnerStartupRunner</code> to the <code>.jar</code> file's
280    manifest. The value should be the name of the class to run at startup. The following
281    snippet shows how you would do this within an <code>ant</code> build script:
282</p>
283<pre>
284&lt;jar jarfile=&quot;myplugin&quot; basedir="&#36;&#123;build.dir&#125;&quot;&gt;
285&lt;manifest&gt;
286&lt;attribute name=&quot;MonkeyRunnerStartupRunner&quot; value=&quot;com.myapp.myplugin&quot;/&gt;
287&lt;/manifest&gt;
288&lt;/jar&gt;
289
290
291</pre>
292<p>
293    To get access to monkeyrunner's runtime environment, the startup class can implement
294    <code>com.google.common.base.Predicate&lt;PythonInterpreter&gt;</code>. For example, this
295    class sets up some variables in the default namespace:
296</p>
297<pre>
298package com.android.example;
299
300import com.google.common.base.Predicate;
301import org.python.util.PythonInterpreter;
302
303public class Main implements Predicate&lt;PythonInterpreter&gt; {
304    &#64;Override
305    public boolean apply(PythonInterpreter anInterpreter) {
306
307        /*
308        * Examples of creating and initializing variables in the monkeyrunner environment's
309        * namespace. During execution, the monkeyrunner program can refer to the variables "newtest"
310        * and "use_emulator"
311        *
312        */
313        anInterpreter.set("newtest", "enabled");
314        anInterpreter.set("use_emulator", 1);
315
316        return true;
317    }
318}
319</pre>
320