As pointed out in an earlier post the importance of testing can not be understated.
In this post we will delve into BDD of Android apps.
There are a number of other testing tools for Android out there, such as Robolectric and Calculon. Robolectric improves the speed of running the test by executing it outside of the emulator. Calculon is a DSL for testing views and activities. As Robotium seems to most mature and reliable, it is my preference.
What is Robotium & what does it do?
Robotium is a test framework created to make it easy to write powerful and robust automatic black-box test cases for Android applications. With the support of Robotium, test case developers can write function, system and acceptance test scenarios, spanning multiple Android activities.
In essence, a Robotium test is a subclass of junit.framework.TestCase (an ActivityInstrumentationTestCase2, in this "case") in which, by use of the Robotium library, a Solo object is created which allows easy access to the views in your activities.
Through the solo object, you can set values in input fields, click on buttons and get results from other UI components. Methods of JUnits Assert class can then be used to check those results.
How to set up Robotium?
After creating an Android Test project in the usual way (I will assume you have done that before), you need to add the robotium JAR to the Libraries on the projects Build Path.
How to use Robotium?
In the setUp method of your testing class, you can create a Solo object and specify the Activity to be started.
The Solo object can then be used in your testXXX methods to get and set values in/from UI components and click buttons and such.
Many of Solos methods to access UI components take an int representing the index of the component in the UI. This can lead to brittle code so using getView (and the id defined in the layout xml) is a much safer alternative.
Do keep in mind that changing values and performing clicks is not allowed from outside of the thread that originally created the views, these things must still be done through Solos methods such as setXXX, EnterText and clickOnXXX.
The values to be asserted can then be retrieved through Solos methods isXXX, getCurrentXXX, searchText and others.
Solos finalize method should be called from the tests tearDown method.
An example:
[sourcecode language="java"]
package xebia.addapptesting;
import xebia.addapp.AddApp;
import xebia.addapp.R;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.EditText;
import com.jayway.android.robotium.solo.Solo;
public class AddTest extends ActivityInstrumentationTestCase2<AddApp> {
private Solo solo;
public AddTest() {
super("xebia.addapp", AddApp.class);
}
@Override
protected void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
}
public void testAdd() {
int one = 1;
int other = 2;
solo.enterText((EditText) solo.getView(R.id.one), Integer.toString(one));
solo.enterText((EditText) solo.getView(R.id.other), Integer.toString(other));
solo.clickOnView(solo.getView(R.id.calcbutton));
assertTrue(solo.searchText(Integer.toString(one + other)));
}
@Override
public void tearDown() throws Exception {
try {
solo.finalize();
} catch (Throwable e) {
e.printStackTrace();
}
getActivity().finish();
super.tearDown();
}
}
[/sourcecode]
When running the test case on the emulator or an actual device, you will see the values being entered into the UI components or see them being clicked as if you were doing it yourself. After the tests are completed, the JUnit view in Eclipse will show which tests have failed and passed.
Conclusion
I think it looks pretty cool to see the app being run and the values being entered. This kind black-box behavior testing on the emulator is much more realistic than just a unit test.
Stay tuned for my next post on a surprise topic, soon!