I will base this post on the last article: Android ViewFlipper within TabHost for Tabs with different Views … and better memory footprint, where we had a TabHost and a ViewFlipper. To test that our example is still working, we have to start the app, start the tab example, click on the ViewFlipper then change to Tab2 and press the button. Of course you can do this by hand if you must, which basically always happens when you’re in the middle of development -unless you’re doing test driven development. But later on, you don’t really want to sit there and click a lot, or even worse, enter text with your thick fingers on a tiny android device screen. So a good idea to test the UI is to get it automated in some way. That is where robotium comes into the game.
Writing a basic test
So let’s write a test that does what we mentioned above. Go through the view and press everything we got and make sure it behaves the way we want it to.
public void testTabExample() { solo.clickOnText("start tab example"); solo.assertCurrentActivity("wrong activiy", Tabs.class); solo.clickOnText("this is a tab one"); assertTrue(solo.searchText("this is the other tab one")); solo.clickOnText("this is the other tab one"); assertTrue(solo.searchText("this is a tab one")); solo.clickOnText("Tab2"); solo.clickOnText("do something"); assertTrue(solo.searchText("this is a tab two")); sendKeys(KeyEvent.KEYCODE_BACK); solo.assertCurrentActivity("wrong activiy", UCdroid.class); }
What we doing here is clicking on the elements we see and clicking on the ones we need to click. We check that we’re running the correct activity and that the right texts show up. The test will run fine now, but it’s missing some abstraction. If we decide to rename a text later, we have to edit the test case. This is less than optimal. So let’s see what we can change to improve the test case.
Changing the application for better testability
Let’s take a look at the layout:
<Button android:id="@+id/btn_tabs" android:text="start tab example" android:layout_width="fill_parent" android:layout_height="wrap_content" />
We can see, that the Button has a hard wired text. That gives us some trouble later, because we cannot look up the text in the string resources. A good idea is to place the appropriate string in strings.xml and put a reference to it in the layout. This has two benefits. First, we can now look up the string in our test case. Second, we now have all the strings we use in the application in one file. This is particularly helpful if we want to have internationalization in the application.
So here is our “new” button
<Button android:id="@+id/btn_tabs" android:text="@+string/btn_start_tab_example" android:layout_width="fill_parent" android:layout_height="wrap_content" />
all we need in the strings.xml now is:
<string name="btn_start_tab_example">start tab example</string>
after we did this for all the strings we use we can continue.
Writing a more abstract test
So here is our improved test case. Now we do not need to fear changing strings or internationalization.
public void testTabExample() { Activity a = getActivity(); String tab1c1 = a.getString(R.string.tab1_content1); String tab1c2 = a.getString(R.string.tab1_content2); String tab2c1 = a.getString(R.string.tab2_content1); solo.clickOnText(a.getString(R.string.btn_start_tab_example)); solo.assertCurrentActivity("wrong activiy", Tabs.class);<img src='http://pragmatic-geek.com/uc/sites/default/files/imagepicker/1/android_logo.jpg' alt='android logo' style="float: left" class="imgp_img" /> solo.clickOnText(tab1c1); assertTrue(solo.searchText(tab1c2)); solo.clickOnText(tab1c2); assertTrue(solo.searchText(tab1c1)); solo.clickOnText(a.getString(R.string.tabexample_tab2)); solo.clickOnText(a.getString(R.string.btn_do_something)); assertTrue(solo.searchText(tab2c1)); sendKeys(KeyEvent.KEYCODE_BACK); solo.assertCurrentActivity("wrong activiy", UCdroid.class); }
Robtium shortcomings
When looking at the robotium java doc I noticed two things so far which bothered me a bit. Maybe I had a wrong approach or didn’t quite figure out how to do it.
When entering text via .enterText(int index, String text) I have to select the EditText field via its position in the layout instead of addressing it by its name. So as soon as the layout changes, I have to edit my test. Not so good.
The next thing is, when menus open and the item to click needs a scrolling action first I cannot reach it.
I’ll try to tackle those issues and write another post on how to do more complex operations.
Robotium alternatives
To all the Futurama fans, there’s another test framework which name has to sound familiar: Calculon. There is a short introduction on the author’s blog. I might look into that too.
So stay tuned for updates on Android UI testing.
Check out the project and the test on github.

Nico Heid

Latest posts by Nico Heid (see all)
- Raspberry Pi Supply Switch, start and shut down your Pi like your PC - August 24, 2015
- Infinite House of Pancakes – code jam 2015 - July 13, 2015
- google code jam 2014 – magic trick - April 18, 2014