Home | History | Annotate | Download | only in help
      1 page.title=monkeyrunner
      2 parent.title=Tools
      3 parent.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
    106 from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
    107 
    108 # Connects to the current device, returning a MonkeyDevice object
    109 device = 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.
    113 device.installPackage('myproject/bin/MyApplication.apk')
    114 
    115 # sets a variable with the package's internal name
    116 package = 'com.example.android.myapplication'
    117 
    118 # sets a variable with the name of an Activity in the package
    119 activity = 'com.example.android.myapplication.MainActivity'
    120 
    121 # sets the name of the component to start
    122 runComponent = package + '/' + activity
    123 
    124 # Runs the component
    125 device.startActivity(component=runComponent)
    126 
    127 # Presses the Menu button
    128 device.press('KEYCODE_MENU', MonkeyDevice.DOWN_AND_UP)
    129 
    130 # Takes a screenshot
    131 result = device.takeSnapshot()
    132 
    133 # Writes the screenshot to a file
    134 result.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>
    168 from 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>
    187 monkeyrunner -plugin &lt;plugin_jar&gt; &lt;program_filename&gt; &lt;program_options&gt;
    188 </pre>
    189 <p>
    190 Table 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>
    239 monkeyrunner help.py &lt;format&gt; &lt;outfile&gt;
    240 </pre>
    241 <p>
    242 The 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>
    298 package com.android.example;
    299 
    300 import com.google.common.base.Predicate;
    301 import org.python.util.PythonInterpreter;
    302 
    303 public 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