Skip to content

Posts tagged ‘beta testing’

Testing with Monkey

December 13, 2011

Apkudo

There’s no point sugar-coating it: testing is not exactly the most fun you can have with a computer. However, it’s an important part of providing a good user experience. Well-tested apps make their users happy, and happy users don’t post incomprehensible one-star reviews like these (taken from a recent sampling of high-ranking Market apps):

On Android, there are many options available for automated testing, starting with the Android Testing Fundamentals page, then moving on to beta testing and advanced automated testing packages like Robotium. But how many people actually use these tools? At Apkudo, we’re interested in questions like these, so we put up a short developer survey. The results are now in (stay tuned for a complete discussion of them in the next couple of weeks) but one number stuck out: 80% of app developers who responded to the survey do not do any form of automated testing.

We’ll go into the “why” of this number a little later: this post is about trying to improve upon the status quo, starting with Monkey: a simple and low-friction automated testing tool.

Introducing Android Monkey

Monkey is a testing utility which simply starts an Android application and sends it a pseudo-random stream of simulated touch and keyboard inputs. In other words, it acts like a monkey with a phone: randomly pressing keys and buttons and touching the screen.

Random key presses and screen touches — how does that help? Surprisingly enough, this simple technique is capable of finding a wide variety of code bugs and errors. It is, of course, by no means a replacement for automated testing, but it’s much better than nothing, and it requires very little manual intervention.

Monkey is installed on most Android devices. To try it out, connect a handset to your computer, and connect to a shell:

adb shell

From there, you can run Monkey on a single package using a command-line like this:

monkey -p com.android.browser 500

This command tells Monkey to start up the Android browser and send 500 pseudo-random events to it. If you run it, you will see Monkey interact with the browser — perhaps by scrolling the page, visiting a bookmark, or similar.

How it works

Behind the scenes, Monkey uses several private interfaces to communicate with three essential system services:

  1. Package Manager: Monkey uses the package manager to get a list of Activities for a given Intent. This enables Monkey to randomly switch between Activities while testing an application.
  2. Activity Manager: Monkey calls the very powerful setActivityController function on the Activity Manager. This effectively gives Monkey complete control over the activity life-cycle for the duration of the test.
  3. Window Manager: Monkey calls a series of functions on the Window Manager to inject events into the application. This enables Monkey to simulate touches and key-presses. Because Monkey communicates at this level, there is no obvious difference between events which have arrived from Monkey and events which have arrived from an actual user. In fact, the distinction is so seamless that it is sometimes necessary to manually check who is in control — hence the famous isUserAMonkey() method in the Android

Monkey sends random events to any application you choose. In order to ensure that this doesn’t cause a security hole, Android uses several techniques to ensure that only monkey can send events, and only when the phone’s user is asking it to.

Firstly, Monkey itself can only be run by root, or by someone in the “shell” Unix group. Normally, only “adb shell” runs as the “shell group”. This means that the only way to run monkey is to do so through “adb shell”.

Secondly, the Monkey application, which is mostly written in Java, asks for two special manifest permissions. The first, SET_ACTIVITY_WATCHER, allows Monkey to take control of the activity life-cycle. The second, INJECT_EVENTS, allows Monkey to simulate touches and key presses. Importantly, no normal Android application can request these permissions — they are only granted to applications supplied with the Android system. So there is little danger of a rogue APK taking control of an Android device using Monkey.

Monkey events

What is an event? In Android, events are sent in  response to user input, or due to system events, such as power management. Monkey supports quite a few event types, but only three of them are of interest for automated testing:

  • KeyEvent: these events are sent by the window manager in response to hardware button presses, and also presses on the keyboard — whether hardware, or on-screen.
  • MotionEvent: sent by the window manager in response to presses on the touchscreen.
  • FlipEvent: sent when the user flips out the hardware keyboard on the HTC Dream. On that device, this would imply an orientation change. Unfortunately, Monkey does not simulate orientation changes on other devices.

Conclusion

Monkey is by no means a replacement for automated testing, but it is a good start in the absence of anything else. Testing your app with Monkey is as simple as installing it an running a short command-line. Stay tuned for the next post in this series, which will explore the types of errors you can find with Monkey.

 

Nicholas Fitzroy-Dale
CTO