Monday, August 20, 2012

Android testing framework - Robotium


Robotium is an Android UI testing framework designed to simplify black-box testing. The framework supports almost all Android related classes such as Activities, Dialogs, Menus, etc. Robotium can be seen as a supplementary to JUnit when you want to automate your tests for Android applications.

When using Robotium, the framework interacts directly with the emulator. It just like if a real user is using your software. You can create the steps for getting the result, identify the expected result and finally, assert the outcome.

There is another testing framework called Robolectric. This framework does not need an emulator to be present. It contains implementation of Android SDK within itself. This speeds up the testing process.

Now, an example using Robotium.

Lets create a sample ui with 2 EditTexts and one DatePicker.
Assume that we have to fill these 2 editTexts and set the calendar to January 1 2011.

Create a class which extends ActivityInstrumentationTestCase2. This class give you the capability to setup a fully functional runtime environment.

Create a no argument constructor and call the super constructor with the Activity under test.

 ActivityInstrumentationTestCase2 defines activity under test which is, in this example MainActivity
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity>

private Solo solo;

public MainActivityTest(){
        super(MainActivity.class);
}

Create a Solo object in setUp method.

@Override 
protected void setUp() throws Exception {
        super.setUp();
By using the method below we can get a reference to the activity under test and starting it if necessary.
        currentActivity = getActivity();
Access Robotium using solo object instantiate it by passing instrumentation and the activity under test
        solo = new Solo(getInstrumentation(), currentActivity);
}

Create a test method for filling the UI.

public void testFillMainActivityUi(){
         String text1 = "first editText";
         String text2 = "second editText";
         get a reference to editTexts
         EditText editText1 = (EditText) currentActivity.findViewById(R.id.editText1);
         EditText editText2 = (EditText) currentActivity.findViewById(R.id.editText2);
        set text for both editTexts
        solo.enterText(editText1, text1);
        solo.enterText(editText2, text2);
        get a reference to datePicker
        DatePicker datePicker = (DatePicker)currentActivity.findViewById(R.id.datePicker1);
        set datePicker value to first Jan 2011 (month starts from zero)
        solo.setDatePicker(datePicker, 2011, 0, 1);
        assert the result
        Assert.assertEquals(text1, editText1.getText().toString());
        Assert.assertEquals(text2, editText2.getText().toString());


        Assert.assertEquals(2011, datePicker.getYear());
        Assert.assertEquals(0, datePicker.getMonth());
        Assert.assertEquals(1, datePicker.getDayOfMonth());
}