Android unit testing: Android testing framework and Robolectric

Problem: There are not many good tutorials on Android unit testing

Android applications are written in Java. So you probably think if you know JUnit, you can unit test Android applications. Surprise! JUnit is not sufficient for unit testing Android applications. Junit works when the code runs within a JVM. Android applications interact with the Android OS. So you need to learn and use a different testing framework.


Why this post?

Qxf2 likes unit testing. Unit testing is one component of an effective testing strategy. Good unit testing rocks. Android unit testing is still in its early days. There are not too many good tutorials that help testers get started with Android unit testing. This post is aimed at helping hands on testers get started with Android unit testing.

NOTE: You can read our other posts on mobile app testing here.


Overview

In this post we will show you two ways of writing and executing unit tests for Android applications:
1) Android testing framework: Android provides a testing framework to run unit tests on both emulators and physical devices.
2) Robolectric: Robolectric provides a unit test framework that allows you to run tests inside the JVM on your computer.

We will use Mileage Tracker app as our the application under test. We chose it because it was open source, the code base was relatively small and came with some unit tests. We will write a simple unit test and run it using both Android test framework and Robolectric.


Part I: Android testing framework

The Android framework provides a testing framework to test your application. Android test suites are based on JUnit 3. We can use JUnit to test a class that doesn’t call the Android API. We should use Android’s JUnit extensions to test Android components. At a high level our steps are:

1. Set up Eclipse ADT
2. Import the test app to eclipse
3. Select a test and check the method
4. Run the test

1. Set up Eclipse ADT
Download the Eclipse ADT and follow the instructions mentioned here

2. Import the test app to eclipse
Create a new “Android Project from Existing Code” and import the downloaded Mileage Tracker app to your eclipse. The Mileage Tracker app also has some sample tests which are already written. Set your root directory and check the projects to import as shown below.

Import Mileage Tracketr app to eclipse

3. Select a test and check the method
The test project already has some tests written to check some of the apps functionality. We will focus on the test VehicleListActivityTest.java which checks the canDelete() method in VehicleListActivity.java in the package com.evancharlton.mileage.

This method returns true if the getAdapter().getCount() is more than 1, else it returns false. This means that in the Vehicle tab you can delete any vehicle information only if there are more than one vehicle information present, else the delete option is not available.

@Override
	public boolean canDelete(int position) {
        return getAdapter().getCount() > 1;
    }

Delete in available only when there more than 2 vehicles

VehicleListActivityTest.java:

package com.evancharlton.mileage;
 
/**
 * Test to check that canDelete() in VehicleListActivity.java in the package com.evancharlton.mileage returns true if the getAdapter().getCount() is more than 1, else returns false. 
*A FakeAdapter class is created which extends BaseAdapter class so that we can set the count using setCount() function 
 */
 
import com.evancharlton.mileage.adapters.FakeAdapter;
import com.evancharlton.mileage.tests.TestCase;
 
public class VehicleListActivityTest extends TestCase {
	protected VehicleListActivity activity;
	// Creating an object of FakeAdaptor class
	private final FakeAdapter mMockAdapter = new FakeAdapter();
 
	protected void setUp() throws Exception {
		super.setUp();
 
		activity = new VehicleListActivity(mMockAdapter);
	}
 
	public void testCanDelete() {
		mMockAdapter.setCount(1); 
		//Since the vehicle count is set to 1 this will return false
		assertFalse(activity.canDelete(0));
 
		mMockAdapter.setCount(2);
		//Since the vehicle count is set to 2 this will return true
		assertTrue(activity.canDelete(0));
	}
}

4. Run the test
Running the test as Android JUnit involves building, deploying, and launching the app in an Android emulator or a physical device, hence the directory structure of MileageTest project is similar to that of Mileage Project. Please refer to this link to set up the run configuration to run your tests either in device or an emulator. If you are running your test using emulator, follow this link for the process on how to create an emulator.

Here is the snapshot of the test run as Android JUnit Test.
– VehicleListActivityTest for the mileage app.
AndroidJunit_run

-Result of the test (using an emulator)
androidjunittest_result

The console output as shown in the above screenshot shows that the MileageTest.apk is installed on the emulator for the test to be executed.


Part II: Android unit testing using Robolectric

Robolectric is a unit testing framework that allows you to write and run tests inside the JVM on your workstation. Robolectric makes this possible by rewriting Android SDK classes as they are being loaded and making it possible for them to run on a regular JVM. Running tests using the Android testing framework involves building, deploying and launching the app in an Android emulator or a physical device. The process is a bit slow. Robolectric addresses some of these concerns. At a high level our steps are:

1. Download Robolectric jar and set up the test app in eclipse
2. Select a method to test
3. Write the test
4. Setting up the Run configuration
5. Running the test

1. Download Robolectric jar and set up the test app in eclipse
Follow the detailed steps given here to download the required jar and set up the Mileage Tracker app. In some cases you may require fest.jar and maps.jar files, you can refer to link to set up Robolectric with these jars.

robolectric_dir_structure

2. Select a method to test
We will test the same canDelete() method as mentioned above for Android unit test.

3. Write the test
To run our test using Robolectric, we will annotate the test using the @RunWith annotation.

package com.evancharlton.mileage;
* Test to check that CanDelete() in VehicleListActivity.java in the package com.evancharlton.mileage returns true if the getAdapter().getCount() is more than 1, 
 * else it returns false. A FakeAdapter class is created which extends BaseAdapter class so that we can set the count using setCount() function 
 */
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import com.evancharlton.mileage.VehicleListActivity;
 
//@Config annotation so that Robolectric emulate an SDK version, since Robolectric doesn't support API level 19 and above
@Config(emulateSdk = 18) 
//To run your test with Robolectric, you need to tell JUnit use the @RunWith annotation
@RunWith(RobolectricTestRunner.class)
 
public class VehicleListActivityTest  {
 
	protected VehicleListActivity activity;
        private final MyAdapter testAdapter = new MyAdapter();
 
 
    @Before
    public void setup() throws Exception {
 
        activity = new VehicleListActivity(testAdapter);
    }
    @Test
    public void testCanDelete() throws Exception 
    {
    	testAdapter.setCount(1);
        //Since the vehicle count is set to 1 this will return false
        assertFalse(activity.canDelete(0));
        testAdapter.setCount(2);
	//Since the vehicle count is set to 2 this will return true
	assertTrue(activity.canDelete(0));
 
    }
 
}

4. Setting up the Run configuration
You can refer to the Setup Run Configuration section in this link to configure it properly. Here is snapshot of the test run configuration for our test project.
Robolectric_run

5. Running the test
Select the Run configuration which you created, run the test and verify the JUnit test result.
Robolectric_result


There you go. Android unit testing is not rocket science.


A weekly newsletter for testers


View a sample



Avinash Shetty
I am a software tester with over 10 years of experience in software testing. Currently I am working at Qxf2 Services Bangalore. As a student of the context-driven approach to software testing I feel there is a lot to learn out there which keeps me very excited. My work has helped me gain good experience in different areas of testing like CRM, Web, Mobile and Database testing. I have good knowledge of building test scripts using Automation tools like Selenium and Appium using Java and Python. Beside testing I am a “Sports Fanatic” and love watching and playing sports.

© 2013-2017, Avinash Shetty. All rights reserved.

One Comment

Leave a Reply

Your email address will not be published.