The latest version of the Android SDK and tools include chimpchat, a library that facilitates the use of monkey from Java. This is equivalent to monkeyrunner, which is the bridge between monkey and the Python scripting language.
While Python is an incredibly powerful and expressive scripting language and will permit you creating tests with just a few statements, there are some occasions when you don't want to introduce a new language to the project leaving your Java confort zone or you prefer to leverage the use of previously created libraries instead of writing new ones.
In such cases, you can now have the same access to monkey running on the device with the help of chimpchat, as we are going to demonstrate.
Creating a Java project
Our first step will be to create a new Java project and we will add the required libraries to the Java Build Path as External Jars.
We are naming the project JavaMonkey, for obvious reasons.
We are adding these libraries from Android SDK, which are used directly or indirectly by our project, to the Java Build Path:
- chimpchat.jar
- ddmlib.jar
- guavalib.jar
- sdklib.jar
JavaMonkey.java
Our intention is to create a simple class, serving the purpose of a simple example to get as started. We will be simply:
Following, is the JavaMonkey class:
Configuration
One of the important things you have to adapt to your environment is the location of the adb command. Otherwise if you don't set it you will receive:
Our intention is to create a simple class, serving the purpose of a simple example to get as started. We will be simply:
- Creating a JavaMonkey object
- initializing it, this implies creating the connection with any emulator or device found or throwing an exception is not connection was made before the timeout expires
- listing all the properties in the device or emulator
- shutting down the connection
Following, is the JavaMonkey class:
/**
* Copyright (C) 2011 Diego Torres Milano
*/
package com.example.javamonkey;
import java.util.TreeMap;
import com.android.chimpchat.ChimpChat;
import com.android.chimpchat.core.IChimpDevice;
/**
* @author diego
*
*/
public class JavaMonkey {
private static final String ADB = "/Users/diego/opt/android-sdk/platform-tools/adb";
private static final long TIMEOUT = 5000;
private ChimpChat mChimpchat;
private IChimpDevice mDevice;
/**
* Constructor
*/
public JavaMonkey() {
super();
TreeMap<String, String> options = new TreeMap<String, String>();
options.put("backend", "adb");
options.put("adbLocation", ADB);
mChimpchat = ChimpChat.getInstance(options);
}
/**
* Initializes the JavaMonkey.
*/
private void init() {
mDevice = mChimpchat.waitForConnection(TIMEOUT, ".*");
if ( mDevice == null ) {
throw new RuntimeException("Couldn't connect.");
}
mDevice.wake();
}
/**
* List all properties.
*/
private void listProperties() {
if ( mDevice == null ) {
throw new IllegalStateException("init() must be called first.");
}
for (String prop: mDevice.getPropertyList()) {
System.out.println(prop + ": " + mDevice.getProperty(prop));
}
}
/**
* Terminates this JavaMonkey.
*/
private void shutdown() {
mChimpchat.shutdown();
mDevice = null;
}
/**
* @param args
*/
public static void main(String[] args) {
final JavaMonkey javaMonkey = new JavaMonkey();
javaMonkey.init();
javaMonkey.listProperties();
javaMonkey.shutdown();
}
}
Configuration
One of the important things you have to adapt to your environment is the location of the adb command. Otherwise if you don't set it you will receive:
E/adb: Failed to get the adb version: Cannot run program "adb": error=2, No such file or directory
Hope this helps you get started with chimpchat. As always, comments and questions are always welcome.

16 comments:
Hi Diego, great post, very helpful, but I'm having an issue, whenever I try to run my java code against a physical device, I inevitably encounter an error:
INFO: Error starting command: monkey --port 12345
com.android.ddmlib.ShellCommandUnresponsiveException
at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:408)
at com.android.ddmlib.Device.executeShellCommand(Device.java:311)
at com.android.chimpchat.adb.AdbChimpDevice$1.run(AdbChimpDevice.java:105)
.
.
I don't see this against an emulator, so I was wondering if you had encountered this situation before? It seems like the default constructor for AdbChimpDevice asynchronously issues the shell command 'monkey --port 12345' which hangs, but I haven't been able to determine why it only affects physical devices.
Perhaps money is not installed on the device you are using for testing. I've run it on my Nexus One with no problems.
Try opening a shell and running monkey from the command line to see if it's there.
Thanks Diego for the great post. This got me started quickly and am able to install a package.
However I am unable to figure out how to start an activity. I was able to do this using the example you have for Python (MonkeyRunner)
runComponent = package + '/' + activity
device.startActivity(component=runComponent)
But in chimpChat startActivity() seem to need a lot more parameters and I am unable to figure out what to pass.
I was wondering if you could help me with this.
Thanks!
Hi Diego, thanks for your posts. I have a problem when i call startActivity method, like Rahul Parekh said. There are a lot of arguments and i can't understand some of them. I'd be pleased if you had some advice for that.
@Rahul Parekh,
Thanks for your comments.
Unfortunately chimpchat is not very clever nor careful about the parameters you pass to some methods and just crashes. So be cautious.
This is an example that works, I hope you can understand is as it will be squished by blogger. I hope you can reconstruct it by Eclipse:
if ( START_ACTIVITY ) {
IChimpDevice device = javaMonkey.getDevice();
String uri = null;
String action = "android.intent.action.MAIN";
String data = null;
String mimeType = null;
Collection categories = new ArrayList();
Map extras = new HashMap();
String pkg = "com.example.i2at.tc";
String activity = "TemperatureConverterActivity";
String component = pkg + "/." + activity;
int flags = 0;
/**
* Start an activity.
*
* @param uri the URI for the Intent
* @param action the action for the Intent
* @param data the data URI for the Intent
* @param mimeType the mime type for the Intent
* @param categories the category names for the Intent
* @param extras the extras to add to the Intent
* @param component the component of the Intent
* @param flags the flags for the Intent
*
* void startActivity(@Nullable String uri, @Nullable String action,
* @Nullable String data, @Nullable String mimeType,
* Collection categories, Map extras, @Nullable String component,
* int flags);
*/
device.startActivity(uri, action, data, mimeType, categories, extras, component, flags);
}
You can try setting some of the parameters to null (i.e. categories) and see how it collapses and give you the completely misleading error:
INFO: Error starting command: monkey --port 12345
Enjoy.
@Rahul Parekh,
Thanks for your comments.
Unfortunately chimpchat is not very clever nor careful about the parameters you pass to some methods and just crashes. So be cautious.
This is an example that works, I hope you can understand is as it will be squished by blogger. I hope you can reconstruct it by Eclipse:
if ( START_ACTIVITY ) {
IChimpDevice device = javaMonkey.getDevice();
String uri = null;
String action = "android.intent.action.MAIN";
String data = null;
String mimeType = null;
Collection categories = new ArrayList();
Map extras = new HashMap();
String pkg = "com.example.i2at.tc";
String activity = "TemperatureConverterActivity";
String component = pkg + "/." + activity;
int flags = 0;
/**
* Start an activity.
*
* @param uri the URI for the Intent
* @param action the action for the Intent
* @param data the data URI for the Intent
* @param mimeType the mime type for the Intent
* @param categories the category names for the Intent
* @param extras the extras to add to the Intent
* @param component the component of the Intent
* @param flags the flags for the Intent
*
* void startActivity(@Nullable String uri, @Nullable String action,
* @Nullable String data, @Nullable String mimeType,
* Collection categories, Map extras, @Nullable String component,
* int flags);
*/
device.startActivity(uri, action, data, mimeType, categories, extras, component, flags);
}
You can try setting some of the parameters to null (i.e. categories) and see how it collapses and give you the completely misleading error:
INFO: Error starting command: monkey --port 12345
Enjoy.
@LH,
Thanks for your comments. Last comment should solve your problem too.
Thanks Diego. I was able to do something similar to what you have mentioned and that resolved my issue.
Hi, when I include this statement-
for (String prop: mDevice.getViewIdList()) {
System.out.println(prop + ": " + mDevice.getProperty(prop));
}
I get following exception:
Apr 14, 2012 6:42:21 PM com.android.chimpchat.ChimpManager sendMonkeyEventAndGetResponse
INFO: Monkey Command: listviews.
Apr 14, 2012 6:42:24 PM com.android.chimpchat.adb.AdbChimpDevice$1 run
INFO: Error starting command: monkey --port 12345
com.android.ddmlib.ShellCommandUnresponsiveException
at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:408)
at com.android.ddmlib.Device.executeShellCommand(Device.java:388)
at com.android.chimpchat.adb.AdbChimpDevice$1.run(AdbChimpDevice.java:105)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Exception in thread "main" java.lang.NullPointerException
at com.android.chimpchat.ChimpManager.parseResponseForExtra(ChimpManager.java:215)
at com.android.chimpchat.ChimpManager.listViewIds(ChimpManager.java:391)
at com.android.chimpchat.adb.AdbChimpDevice.getViewIdList(AdbChimpDevice.java:585)
at com.example.javamonkey.JavaMonkey.listProperties(JavaMonkey.java:59)
at com.example.javamonkey.JavaMonkey.main(JavaMonkey.java:78)
@Rahul parekh, @Diego
In previous comment you have told the issue is resolved regarding the chimpchat startactivity. Could please help me.
I am not able to compile as it shows compiler error:
The method startActivity(String, String, String, String, Collection, Map, String, int) in the type
IChimpDevice is not applicable for the arguments (String, String, null, null, Collection, Map, String, String)
Flags (last argument for startActivity()) is int, you are passing a String.
@Diego
Thanks, a silly mistake it is working.
Is there a way to do screenshot comparision using chimpchat?
@Diego
Can i click on a view with the help of the text on view with Chimpchat.
@Anand P,
This articles may help you:
monkeyrunner: testing Views properties
AndroidViewClient: Q&A
Post a Comment