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.

Standard

9 thoughts on “Example Robolectric and Ant Eclipse Project

  1. Billy says:

    Great article, however I tried running these tests in eclipse, and keep getting the following warnings from the console:

    Warning: an error occurred while binding shadow class: ShadowNdefMessage
    Warning: an error occurred while binding shadow class: ShadowNdefRecord
    Warning: an error occurred while binding shadow class: ShadowNfcAdapter

    what could that be a result of?

    Thanks,

    Billy

  2. Glad you enjoyed the article, Billy.

    The warnings about binding to shadow classes are because you’re using a version of the Android.jar file that doesn’t contain those classes.

    You’re probably pointing at an older Android.jar file with a newer Robolectric.jar. :)

    Hope that helps.

  3. James says:

    I can run the base project no problem, but android-project-test won’t compile.

    Unbound classpath variable: ‘CLASSPATH’ in project ‘android-project-test’

  4. James says:

    Nevermind. I don’t know why pointing to a nonexistent android SDK (android-8) would make that error occur, but when I updated the manifest in android-project to have a min SDK of 12 it ran.

    I’m having another issue witht he conversion of the reports after it passes in an ant build, but that’s probably user error too. :-)

  5. Jason says:

    Specifically, there isn’t a RobolectricConfig class anymore, which undermines your solution. I’ve tried adding it back to the robolectric source, but I’m getting tons of compile errors upon trying to create my own jar.

    And obviously having both new and old jars won’t work.

  6. Jason says:

    Got it working with the @Config(manifest="/path/to/projectbeingtested/AndroidManifest.xml") which tells Robolectric how to resolve references to your Android project’s manifest and resources. Thanks again.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Powered by sweet Captcha