Search code examples
pythonandroid-emulatorjythonmonkeyrunner

Android's MonkeyRunner occasionally throws exceptions


I am running an automated test using an Android emulator driving an app with a Monkey script written in Python. The script is copying files onto the emulator, clicks buttons in the app and reacts depending on the activities that the software triggers during its operation. The script is supposed to be running the cycle a few thousand times so I have this in a loop to run the adb tool to copy the files, start the activities and see how the software is reacting by calling the getProperty method on the device with the parameter 'am.current.comp.class'. So here is a very simplified version of my script:

for target in targets:
    androidSDK.copyFile(emulatorName, target, '/mnt/sdcard')

    # Runs the component
    device.startActivity(component='com.myPackage/com.myPackage.myactivity')

    while 1:
        if device.getProperty('am.current.comp.class') == 'com.myPackage.anotheractivity':
            time.sleep(1) # to allow the scree to display the new activity before I click on it
            device.touch(100, 100, 'DOWN_AND_UP')
            # Log the result of the operation somewhere
            break

        time.sleep(0.1)

(androidSDK is a small class I've written that wraps some utility functions to copy and delete files using the adb tool).

On occasions the script crashes with one of a number of exceptions, for instance (I am leaving out the full stack trace)

[com.android.chimpchat.adb.AdbChimpDevice]com.android.ddmlib.ShellCommandUnresponsiveException

or

[com.android.chimpchat.adb.AdbChimpDevice] Unable to get variable: am.current.comp.class
[com.android.chimpchat.adb.AdbChimpDevice]java.net.SocketException: Software caused connectionabort: socket write error

I have read that sometimes the socket connection to the device becomes unstable and may need a restart (adb start-server and adb kill-server come in useful).

The problem I'm having is that the tools are throwing Java exceptions (Monkey runs in Jython), but I am not sure how those can be trapped from within my Python script. I would like to be able to determine the exact cause of the failure inside the script and recover the situation so I can carry on with my iterations (re-establish the connection, for instance? Would for instance re-initialising my device with another call to MonkeyRunner.waitForConnection be enough?).

Any ideas?

Many thanks, Alberto

EDIT. I thought I'd mention that I have discovered that it is possible to catch Java-specific exceptions in a Jython script, should anyone need this:

from java.net import SocketException

...

try:
    ...

except(SocketException):
    ...

Solution

  • It is possible to catch Java-specific exceptions in a Jython script:

    from java.net import SocketException
    
    ...
    
    try:
        ...
    
    except(SocketException):
        ...
    

    (Taken from OP's edit to his question)