Sunday, November 16, 2008

Test-driving Android GUI

It happened again that I received an e-mail from somebody asking whether there is a way to automate the testing of Android user interfaces. I did not know so I went after the issue and to my utter surprise, I discovered that an entire unit test framework has been developed into Android while I looked the other way. In this blog entry, I will describe my experiences with the Android instrumentation framework.

You can download the example program from here.

The idea behind Android instrumentation framework is that there are instrumentation components that resemble a lot the usual Activities. The purpose of these instrumentation components, however, is to test-drive other, normal Activities. Let's see the example program!

Install the package in the bin directory as usual:

adb install instrumentation-debug.apk

If the package has been installed before, you first have to uninstall it. This is new in the 1.0 version of the SDK, previously the new installation would simply overwrite the old one.

adb uninstall aexp.instrumentation

Two applications appear in the application folder. "Calculator" is a primitive calculator application used as test target. You can launch it independently and try it yourself. If you launch "Calculator instrumentation launcher", you will be confronted with a button to launch Calculator instrumentation. Once you push it, the calculator launches but its input keypresses will come from the instrumentation component. You will see the input fields filled up automatically, the addition button pushed and the result displayed. Then both the calculator instance and the launcher will disappear but if you check the logs (adb logcat), you will see that the test was successful.


The key instruction is in CalculatorInstrumentationLauncher.java where the instrumentation component is launched:

startInstrumentation(
new ComponentName(
CalculatorInstrumentationLauncher.this,
CalculatorInstrumentation.class ),
null,
null );

This launches CalculatorInstrumentation component which is a descendant of android.app.Instrumentation. The instrumentation component resembles a normal Activity, except that it is able to drive user input of other activities. This time we launch the Calculator, feed in keypresses (sendCharacterSync()) and invoke one of its method to obtain the result. Note the usage of runOnMainSync() method when we invoke Calculator's method to obtain the result.

It is definitely cool that Android has a user interface-oriented unit testing framework built into the platform. Maybe I am ignorant but I am not aware of any other platform that has this capability. In order to Test Driven Development (TDD), we need a proper unit testing framework and Android has even JUnit integrated. More about that later.

17 comments:

Kamal said...

Nice example Gabor !!

Anonymous said...

Hi, I am new to Android SDK.I tried the same application.
But Im not able to launch the calculator appliaction from the CalculatorInstrumenattionLauncher App. I created the Calculator, CalculatorInstrumentation & CalculatorInstrumentationLauncher JAVA files in the package of the same project. Even I modified the Manifest.xml also, but still iam not able to launch the app.
Could you please assist me in this.
Thanks in advance

Anonymous said...

I forgotten to give my mail ID.
it is siva.gv@gmail.com

ele-android-test said...

cool~

我本善良 said...

Thanks for you example, but i can not download the sample, could you please send me a copy, many thanks!!

ontest@sina.com

Mayank said...

Hey Gabor,
Can you please elaborate or direct me something related to TDD.I have a app i need to built a set of unit test cases before the actual code is written and port to android environment.

vaibhav said...

Thanks Gabor.

Amit Mhatre said...

Hi,
really good article.
Is there any testing process or submission checklist before app submission to android market place

Thanks
Amit M

Gabor Paller said...

"Is there any testing process or submission checklist before app submission to android market place"

I have no idea. :-)

Vere said...

Hi,Gabor
Thank you for your example. I tried to build your example in android platform 2.0.1. The activity "Calculator instrumentation launcher" started then I clicked the "Launch Calculator Instrmentation" button, but nothing happen.

A warning text appears "01-14 09:00:31.029: WARN/ActivityManager(57): Unable to find instrumentation info for: ComponentInfo{com.demo.android.calculator/com.demo.android.calculator.CalculatorInstrumentation}" in eclipse console.

Could you give me a hit about this?
Thank you.

Gabor Paller said...

Vere, I tried the example on 2.0.1 and it worked for me.

Download the example in 2.0.1 project structure from here.

Anonymous said...

Why not just use Robotium instead? It makes android testing so much easier.

Swapnil said...

I am facing some problems in injecting motion events. Its a permission issue even if INJECT_EVENT permission is there in Manifest. Do you have any sample for inject motion events.

Gabor Paller said...

"Its a permission issue even if INJECT_EVENT permission is there in Manifest."

That permission has to be applicable to the window server. Granting your application that permission does not help.

Swapnil said...

Now how to grant permission to the Window Server ?

Anonymous said...

can we use instrumentation testing on existing android applications like music player, camera and gallery or is it only for applications which we develop

manju said...

Hi gabor,
i want to automate Phone app (native application) is it possible to automate it using instrumentation ?

manju.