Android Robotium. This tutorial describes how to test Android applications with the Android Robotium testing framework.

1. Robotium

Robotium is an extension of the Android test framework and was created to make it easy to write user interface tests for Android applications. Robotium tests inherit from ActivityInstrumentationTestCase2 and allows you to define test cases across Android activities.

Robotium tests perceive the application under test as black box, i.e., it only interacts with the user interface and not via the internal code of the application.

The homepage of Robotium is currently located under the following URL: Robotium homepage but is moving to Robotium at Github.

Robotium extends the Android test framework to make it simpler to write tests. The main class for testing with Robotium is Solo.

Solo is initialized with the instrumentation of the testcase and the first activity to test.

2. Installation of Robotium

To use Robotium in your Android test project, you need to add a dependency to the latest Robotium release to your build file.

dependencies {
    // Unit testing dependencies
    androidTestCompile 'com.jayway.android.robotium:robotium:5.4.12'
}

At the time of this writing the latest Robotium version is 5.4.1.

3. Example Robotium tests

The following code demonstrates the usage of Robotium in an activity user interface test.

package de.vogella.android.test.target.test;

import junit.framework.Assert;
import android.test.ActivityInstrumentationTestCase2;

import com.robotium.solo.Solo;

import de.vogella.android.test.target.SimpleActivity;
import de.vogella.android.test.target.SimpleListActivity;

public class SimpleActivityTest extends
        ActivityInstrumentationTestCase2<SimpleActivity> {

    private Solo solo;

    public SimpleActivityTest() {
        super(SimpleActivity.class);
    }

    public void setUp() throws Exception {
        solo = new Solo(getInstrumentation(), getActivity());
    }


    @Override
    public void tearDown() throws Exception {
        solo.finishOpenedActivities();
    }
}

The following shows another example for the Robotium test method which tests a list implementation.

// check that we have the right activity
solo.assertCurrentActivity("wrong activity", SimpleActivity.class);

// Click a button which will start a new Activity
// Here we use the ID of the string to find the right button
solo.clickOnButton(solo.getString(R.string.button1));
// Validate that the Activity is the correct one
solo.assertCurrentActivity("wrong activity", SimpleListActivity.class);
solo.clickInList(1);
// searchForText has a timeout of 5 seconds
assertTrue(solo.waitForText("Android")); // Assertion
solo.clickInList(2);
assertTrue(solo.waitForText("iPhone")); // Assertion
solo.clickInList(3);
assertTrue(solo.waitForText("Blackberry")); // Assertion
solo.goBack();
solo.clickOnButton("Button2");
solo.clickOnButton("Button3");

// open the menu
solo.sendKey(Solo.MENU);
solo.clickOnText("Preferences");
solo.clickOnText("User");
solo.clearEditText(0);
Assert.assertTrue(solo.searchText(""));
solo.enterText(0, "http//:www.vogella.com");
Assert.assertTrue(solo.searchText("http//:www.vogella.com"));
solo.goBack();

4. Robotium API

Solo provides methods to call the Android user interface. The following table lists several of these methods.

Table 1. Test methods on Solo
Method Description

getView(int id)

Searches for the view with the specified ID in the current activity.

assertCurrentActivity(text, Activity.class)

Ensure that the current activity equals the second parameter.

getCurrentActivity() .getFragmentManager() .findFragmentById()

Searches for a fragment.

waitForText(text)

Waits for a text on the screen, default timeout 5 seconds.

clickOnButton(text)

Clicks on a button with the "text" text.

sendKey(Solo.MENU);

Sends the menu key event.

clickOnText(text)

Search for text in the current user interface and clicks on it.

enterText()

Enters a text.

searchText(text)

Searches for a text in the current user interface, return true if found.

searchButton(text)

Searches for a button with the text in the current user

clickOnSearch()

Allows to click on part of the screen.

goBack()

Press the back button.

setDatePicker()

Sets the date in a DatePicker.

clickInList(x);

Click on item number x in a ListView

pressSpinnerItem(0,2);

Presses an item in a Spinner

isCheckBoxChecked()

Checks if the checkbox is checked.

takeScreenshot()

Saves a screenshot on the device in the /sdcard/Robotium-Screenshots/ folder. Requires the android.permission.WRITE_EXTERNAL_STORAGE permission in the AndroidManifest.xml of the application under test.

waitForActivity(SecondActivity.class, 2000)

Waits for the specified activity for 2 seconds

Via the solo.setActivityOrientation(Solo.LANDSCAPE) method you can set the orientation of the activity.

To test internationalized strings you can access the string resources file from the project under test via the getString(id) method. For example:

// Here we use the ID of the string to find the right button
solo.clickOnButton(solo.getString(de.vogella.android.test.target.R.string.button1));

5. Executing tests

To run a Robotium test use the same approach you use to run Eclipse, right-click the test class and select Run-As  Android JUnit Test

You can run Robotium tests from the command line, too.

adb shell am instrument
  -w de.vogella.android.test.tester/android.test.InstrumentationTestRunner

6. Exercise: Write Robotium tests

6.1. Exercise: Writing Robotium tests

Create an Android project called com.vogella.android.test.robotium.target. Display three buttons in the first activity. If the first button is pressed, start another activity which displays a list.

6.2. Create test project and add Robotium

Create a test project called com.vogella.android.test.robotium.targetTest. Create a folder called libs and place the Robotium JAR file into it.

TIP:If you place the JAR file in this folder, the Android tooling for Eclipse adds it automatically to the build path of your project. Putting the JAR into a folder with a different name, frequently causes a ClassNotFoundExeception for the Solo class.

6.3. Create test project and add Robotium library

Define the following test class.

package de.vogella.android.test.target.test;

import junit.framework.Assert;
import android.test.ActivityInstrumentationTestCase2;

import com.robotium.solo.Solo;

import de.vogella.android.test.target.SimpleActivity;
import de.vogella.android.test.target.SimpleListActivity;

public class SimpleActivityTest extends
        ActivityInstrumentationTestCase2<SimpleActivity> {

    private Solo solo;

    public SimpleActivityTest() {
        super(SimpleActivity.class);
    }

    public void setUp() throws Exception {
        solo = new Solo(getInstrumentation(), getActivity());
    }

    @Override
    public void tearDown() throws Exception {
        solo.finishOpenedActivities();
    }

    public void testListItemClickShouldDisplayToast() throws Exception {
        // check that we have the right activity
        solo.assertCurrentActivity("wrong activity", SimpleActivity.class);

        // Click a button which will start a new Activity
        // Here we use the ID of the string to find the right button
        solo.clickOnButton(solo
                .getString(de.vogella.android.test.target.R.string.button1));
        // assert that the current activity is the SimpleListActivity.class
        solo.assertCurrentActivity("wrong activity", SimpleListActivity.class);
        solo.clickInList(1);
        // searchForText has a timeout of 5 seconds
        assertTrue(solo.waitForText("Android")); // Assertion
        solo.clickInList(2);
        assertTrue(solo.waitForText("iPhone")); // Assertion
        solo.clickInList(3);
        assertTrue(solo.waitForText("Blackberry")); // Assertion
        solo.goBack();
        solo.clickOnButton("Button2");
        solo.clickOnButton("Button3");
    }

    public void testListItemClickShouldDisplayToast() throws Exception {
        // open the menu
        solo.sendKey(Solo.MENU);
        solo.clickOnText("Preferences");
        solo.clickOnText("User");
        solo.clearEditText(0);
        Assert.assertTrue(solo.searchText(""));
        solo.enterText(0, "http//:www.vogella.com");
        Assert.assertTrue(solo.searchText("http//:www.vogella.com"));
        solo.goBack();

    }

}

6.4. Fix your application

Assume that the test is your specification and adjust your Android application until the test passes correctly.