Example Robolectric and Ant Eclipse Project

Until recently, I’ve been unable to configure a Robolectric project that can easily be shared across a team and integrated with Jenkins CI without the use of Maven. I mentioned this in a previous post, and have asked for assistance on Pivotal’s Robolectric Google Group a handful of times. There are several jar files that need to be referenced, and dependencies between the test and main Android projects and (without the use of Maven) this is difficult to configure and move around between teammates.

Thankfully, a brilliant Android engineer named Michael Portuesi came to my aid and helped me sort out the missing pieces, and I decided to create an example Robolectric project to share his wisdom and help other people get started. This project also includes an Ant script that you can easily plug into Jenkins or any other Ant-based CI process.

How does it work?

A Robolectric test project requires dependencies on:

  • android.jar
  • maps.jar
  • junit.jar
  • hamcrest.jar
  • robolectric-with-dependencies.jar
  • The Android project being tested

There are several ways you can set this up, but for simplicity I’ve pinned these jar files into the test project’s libs folder. Some people prefer linking the Robolectric source into their test projects, so they can modify the Robolectric code as necessary. You can also use environment variables in place of the Maps and Android jars, and add references to JUnit and Hamcrest to your test project’s build path via Eclipse.

After cloning this repository, add the android-project and android-project-test projects into an Eclipse workspace. The android-project is an Android project (obviously), and the android-project-test project is a plain old Java project. You should be able to right-click on the android-project-test project, and choose “Run As -> JUnit Test”, and the single test should run via Robolectric and JUnit. Alternatively, you should be able to right-click on the build.xml file and choose “Run As -> Ant Build”. This ant script can be used to run your Robolectric tests via a CI server like Jenkins.

Take note of SampleTestRunner.java. This class inherits from RobolectricTestRunner, and tells Robolectric how to resolve references to your Android project’s manifest and resources:

package com.justinschultz.tests.runner;

import java.io.File;

import org.junit.runners.model.InitializationError;

import com.xtremelabs.robolectric.RobolectricConfig;
import com.xtremelabs.robolectric.RobolectricTestRunner;

public class SampleTestRunner extends RobolectricTestRunner {
	/**
	 * Call this constructor to specify the location of resources and AndroidManifest.xml.
	 * 
	 * @param testClass
	 * @throws InitializationError
	 */	
	public SampleTestRunner(@SuppressWarnings("rawtypes") Class testClass) throws InitializationError {
		super(testClass, new RobolectricConfig(new File("../android-project/AndroidManifest.xml"), new File("../android-project/res")));
	}
}

When authoring tests, make sure your class names end with the word “Test”, as the ant script requires this. Also make sure that their @RunWith annotations use the SampleTestRunner.class, and NOT the RobolectricTestRunner.class:

@RunWith(SampleTestRunner.class)
public class SampleTest {
    @Test
    public void testBasicResourceValue() throws Exception {
        String helloFromActivity = new MainActivity().getResources().getString(R.string.hello);
        assertThat(helloFromActivity, equalTo("Hello World, MainActivity!"));
    }
}

Finally, make sure junit.jar is defined in your Ant script’s classpath BEFORE android.jar, otherwise Ant will throw an error:

	<path id="junit_classpath">
		<pathelement path="${build.dir}"/>
		<pathelement path="${android.project.classpath}"/>
		<!-- NOTE: junit.jar must come before android.jar! -->
		<filelist refid="libs_jars"/>
		<filelist refid="android_jars"/>
	</path>

And that’s it. You should be able to clone the Android Eclipse Robolectric Example from GitHub and immediately run the sample test via Ant or JUnit in Eclipse.


About this entry