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 <module> 169</pre> 170<p> 171 where <code><module></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 <plugin_jar> <program_filename> <program_options> 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 <plugin_jar></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><program_filename></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><program_options></code> 228 </td> 229 <td> 230 (Optional) Flags and arguments for the program in <program_file>. 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 <format> <outfile> 240</pre> 241<p> 242The arguments are: 243</p> 244 <ul> 245 <li> 246 <code><format></code> is either <code>text</code> for plain text output 247 or <code>html</code> for HTML output. 248 </li> 249 <li> 250 <code><outfile></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 <plugin_jar></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<jar jarfile="myplugin" basedir="${build.dir}"> 285<manifest> 286<attribute name="MonkeyRunnerStartupRunner" value="com.myapp.myplugin"/> 287</manifest> 288</jar> 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<PythonInterpreter></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<PythonInterpreter> { 304 @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