The following is the first few sections of a chapter from The Busy Coder's Guide to Android Development, plus headings for the remaining major sections, to give you an idea about the content of the chapter.
Many GUI environments have some means or another of “fuzz” or “bash” testing, where some test driver executes a bunch of random input, in hopes of catching errors (e.g., missing validation logic). Android offers the Test Monkey for this.
Many GUI environments have some means or another of scripting GUI events from outside the application itself, to simulate button clicks or touch events. Android offers MonkeyRunner for this.
As the names suggest, there is a bit of commonality in their implementation. And, as you might expect, there is a bit of commonality in their coverage in this book — we will examine both MonkeyRunner and the Test Monkey in this chapter.
Understanding this chapter requires that you have read the core chapters of this book.
MonkeyRunner is a means of creating test suites for Android applications based on scripted UI input. Rather than write a series of JUnit test cases or the like, you create Jython (JVM implementation of Python) scripts that run commands to install apps, execute GUI events, and take screenshots of results.
The primary object you will work with in a MonkeyRunner script is a
which represents your connection to the device or emulator that you are testing.
You obtain a
MonkeyDevice by calling
MonkeyRunner; this will
return once it has established a connection.
MonkeyDevice lets you send events to the device or emulator:
installPackage()allows you to install an APK from your development machine, and
removePackage()allows you to get rid of it
broadcastIntent()allow you to start up components of your app
press()to simulate key events, including QWERTY keys, standard device keys like BACK, D-pad/trackball events, and anything else represented by a standard Android
type()to simulate entering a whole string, as a simplification over calling
press()once per letter
drag()let you simulate touch events
The biggest limitation is in getting data out of the device, to determine if your test worked successfully. Your options are:
takeSnapshot(), which will capture a screenshot that you can save to disk, compare with other screenshots, etc.
adb shellcommands, returning any results
Unlike JUnit-based testing, you have no visibility into the activity beyond what appears on the screen — you cannot inspect widgets, call methods, or the like.
For example, here is a script that installs an app, runs an activity from it, and presses the down button on the D-pad three times:
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice device = MonkeyRunner.waitForConnection() device.installPackage('bin/JUnitDemo.apk') device.startActivity(component='com.commonsware.android.abf/com.commonsware.android.abf.ActionBarFragmentActivity') device.press('KEYCODE_DPAD_DOWN', MonkeyDevice.DOWN_AND_UP) device.press('KEYCODE_DPAD_DOWN', MonkeyDevice.DOWN_AND_UP) device.press('KEYCODE_DPAD_DOWN', MonkeyDevice.DOWN_AND_UP) # result = device.takeSnapshot() # result.writeToFile('tests/monkey_sample_shots/test1.png', 'png')
To execute your MonkeyRunner script, have your device or emulator set up at a likely
starting point (e.g., home screen), then execute the
passing it the path to your script (e.g.,
monkeyrunner monkey_sample.py). You will
see the script executing on the screen of your device or emulator, and your console
will contain whatever output you might emit from your test script itself. For example,
you might take screenshots, compare them against a master copy (using methods
MonkeyImage to help with this), and emit warnings if they differ unexpectedly.
The preview of this section was whisked away by a shark-infested tornado.