Thursday, February 16, 2012
Testing Android User Interfaces with Robotium
Overview
Android provides a 'test project' framework and various tools for testing apps. Robotium is an opensource project which enhances these facilities. Robotium provides convenience and utility methods which simplify clicking buttons, accessing text fields, etc. Robotium hides the underlying syntax and procedures.
Tests can be run on emulators as well as real devices.
Tests can be started within eclipse as well as from a command-line.
Testcase methods can access localized message strings.
Setup
- Create the Android app to be tested (aka app-under-test).
- Create a basic Android Test Project associated with your app-under-test. Follow basic Android instructions:
http://developer.android.com/resources/tutorials/testing/helloandroid_test.html
- Verify it runs.
From Eclipse package explorer, right-click the test project-> Run As-> Android JUnit Test.
- Fetch the Robotium jar file:
http://code.google.com/p/robotium/ -> Downloads -> robotium-solo-3.1.jar (or later)
Optional: Fetch the javadoc.
- Add the Robotium jar file to the test project 'libs' directory
From Eclipse-> right click test project-> Properties-> Java build path-> Add external jars-> point to jar.
- In your testcase class, import the Robotium Solo class and define a reference to a Solo object:
import com.jayway.android.robotium.solo.Solo;
private Solo mSolo;
Fix your dependencies and get your testcase class to compile.
- Instantiate a Solo object in one of your testcase methods:
// Instantiate a new Solo object.
mSolo = new Solo(getInstrumentation(), getActivity());
Verify it runs. You are now ready to make use of Robotium...
Using Robotium
Study the methods available in class Solo. Either read the javadoc or browse the source:
https://github.com/jayway/robotium/tree/master/robotium-solo/src/main/java/com/jayway/android/robotium/solo
- Access widgets in your app-under-test using Solo. Examples:
-- My app-under-test contains one ToggleButton. Since there is only one, I can use the index '0' to query this ToggleButton:
// Query whether the button is checked.
boolean checked = mSolo.isToggleButtonChecked(0)
-- My ToggleButton text is defined as 'OFF' and 'ON'. To click the ToggleButton, I use the name:
// Click the OFF button to ON.
mSolo.clickOnToggleButton("OFF");
Note that the 'name' of a ToggleButton changes from 'OFF' to 'ON' depending upon its state. To click it again when it is on, issue the following:
// Click the ON button to OFF.
mSolo.clickOnToggleButton("ON");
-- My app also has one TextView which displays various messages. I can use Robotium Solo to query if a message is visible:
// Query whether the message is displayed.
boolean found = mSolo.searchText("green apples");
-- Robotium also has a set of methods named 'waitForText' with various parameters. I look forward to using these.
Internationalization
Rich apps display text messages in various languages. Testcases which search for text strings must be able to access the localized string. The basic Android test project supports this, and it works with Robotium as well.
I added several strings to be translated in my app-under-test. From res/values/strings.xml:
<string name="on">ON</string>
<string name="off">OFF</string>
<string name="green_apples">green apples</string>
I internationalized my toggle button to use these values:
<ToggleButton
...
android:textOn="@string/on"
android:textOff="@string/off" >
</ToggleButton>
Then within the test project...
// Get localized strings.
int idOff = com.example.app-under-test-package-name.R.string.off;
String off = getActivity().getResources().getString(idOff);
// Click the OFF button to ON.
mSolo.clickOnToggleButton(off);
Similarly for text fields...
int idGreenApples = com.example.app-under-test-package-name.R.string.green_apples;
String greenApples = getActivity().getResources().getString(idGreenApples);
// Query whether the message is displayed.
boolean found = mSolo.searchText(greenApples);
Execution
There are two ways to invoke tests...
From eclipse package explorer, right-click the test project-> Run As-> Android JUnit Test. Eclipse first installs the app-under-test APK and the testcase APK. Then it switches to the familiar JUnit view which shows a list of tests as they run, along with a progress bar.
From a command-line, issue ADB commands to install both APKs, then issue an ADB command to start the testcase app (specifying your testcase package name and the Android InstrumentationTestRunner). Example:
# Install the app-under-test.
adb install -r app-under-test.apk
# Install the test app.
adb install -r testcases.apk
# Start the test app:
adb shell am instrument -w com.example.test-package-name/android.test.InstrumentationTestRunner
In both cases, you can watch the tests run on your emulator or real device.
Execution on multiple devices
If you have several real devices attached to your computer via USB cable, you can run all the tests in parallel, from different command-line windows (or through fancy scripting). To do this, you must specify the device ID. First query the list of devices (obfuscated results):
adb devices
List of devices attached
S84KD9G0D0F4 device
P40D9GKKRKD8 device
Then target each ADB command to a specific device. Example:
adb -s S84KD9G0D0F4 install -r app-under-test.apk
Summary
Robotium provides a large set of convenience methods for accessing widgets and text fields, which makes your testcases smaller, simpler, and easier to understand. Very nice. Study the methods and make use of them.
References:
Android Test Guide: http://developer.android.com/guide/topics/testing/testing_android.html
Robotium: http://robotium.org
Tutorials: http://lmgtfy.com/?q=robotium+tutorial
Subscribe to:
Post Comments (Atom)
Did the method/code you specified under 'Internationalization' para will work in case when we doesn't have the sopurce code of the app??? As we doesn't have the source code of apk.
ReplyDelete