Monday, January 31, 2011

Obtaining Android screenshots in tests with monkeyrunner

Today I helped somebody that was asking why an extremely simple monkeyrunner script fails to obtain the screenshot.
Interestingly enough, this script was almost a verbatim copy of what is specified in monkeyrunner documentation. So you guessed, the documentation is wrong and unfortunately there is no way of correcting it, Android documentation is not a wiki and the only way is reporting a bug that will be probably ignored sunk in a sea of thousands more important bugs.

So here you have the problem and the solution.

The problem
The documentation includes this line to take the screenshot:

# Takes a screenshot
result = device.takeSnapShot

if you run this, you soon realize that something is wrong. You will receive an error similar to this one:

AttributeError: '' object has no attribute 'takeSnapShot'

The problem, or better I should say the problems, because there are two, are:
  1. missing parenthesis, so instead of using the call operator on the callable object we are getting a reference to the object itself and then try to access one attribute
  2. if there were parenthesis, the call won't succeed anyway because the second 'S' is lowercase 's'

The solution
Then this is the complete solution to obtain the screenshot:

# Imports the monkeyrunner modules used by this program
from import MonkeyRunner, MonkeyDevice
# Connects to the current device, returning a MonkeyDevice object
device = MonkeyRunner.waitForConnection()
# Takes a screenshot
result = device.takeSnapshot()
# Writes the screenshot to a file

Extra tip
You can add the corresponding she-bang to the script and set the execution permission to be able to run it from the command line just invoking the script name:

#! /opt/android-sdk-linux_86/tools/monkeyrunner
This should include the path to your monkeyrunner script, and because it uses Jython, an implementation of Python that uses the Java programming language, thus allowing the use of Python syntax to access the constants, classes, and methods of the API.
Having added this she-bang line you can simply run your monkeyrunner script by invoking its name:

  $ monkeyrunner-take-screenshot


Amit said...

Thanks, just wanted to say that this tip did help me. :-)

Senare said...

Nice and helpful ... but if it's not been to long. Would you maybe care to elaborate on the shebang ? Wont i have to specify the location of phyton then or jython ?

Diego Torres Milano said...

Thanks fro your comments.
I added some clarification to the she-bang section.