Robolectric and Cobertura with Gradle

Update 2 (July 29 2015): Even better! Just use unit testing support of the Android Gradle plugin. As of Robolectric 3.0 you also no longer need any Robolectric Gradle plugin.

Update (Apr 03 2015): You can now just use the Robolectric Gradle plugin. It works like a charm and avoids a lot of manual setup.

DEPRECATED

Recently I have been working to set up code coverage reports for an Android project using Cobertura. I had already set up Robolectric manually and there is a working Cobertura Gradle plugin available. This left me with figuring out how to hook up the two. In general the following steps are needed to use Cobertura with any testing framework:

  • Make sure you fork the JVM.
  • Point the “net.sourceforge.cobertura.datafile” system property to your “cobertura.ser” file location.
  • Add the instrumented classes to the front of the class path.
  • Add cobertura classes to the class path.

You can read more about Cobertura setup in the “Ant Task Reference” on the Cobertura Wiki.

My first problem was that the Cobertura plugin automatically adds the Java plugin. The Android plugin doesn’t play nice with the Java plugin, so that had to be solved. The solution was to put all Coberture related configuration in its own Gradle build file without the Android Gradle plugin applied. All the Cobertura plugin needs to do after all is inspect compiled (and instrumented) code.

After this it was a matter of configuring the Cobertura and Robolectric plugins correctly and running tasks in the right order.

Cobertura Gradle configuration
To be able to instrument all classes, I pointed the “coverageDirs” property to a list of build folders from my project and subprojects.
NOTE: You may need to set up the “auxiliaryClasspath” if you get some “ClassNotFoundException” errors.

If you want the source code to show up correctly in your reports, make sure to configure the “coverageSourceDirs” property.

Cobertura will inspect all classes you point to in the “coverageDirs” property. To exclude any classes generated by the Android framework, add the following to the “coverageExcludes” property:

  • “.*\\.package-info.*” for package-info files,
  • “.*\\.R.*” for generated R classes and
  • “.*BuildConfig.*” for any BuildConfig classes.

Robolectric Gradle configuration
Add the following to you Gradle build file so the instrumented classes are able to write their reports:

  1. systemProperties["net.sourceforge.cobertura.datafile"] = "your_cobertura_ser"

In the Robolectric test compile dependencies, make sure you add the path to the instrumented classes in front of everything else.

Don’t forget to add “net.sourceforge.cobertura:cobertura:2.0.3” to your test compile dependencies as well.

Putting it all together
Now all plugin configuration is done, you can run tests and have the coverage reports generated by executing the following commands. Note that this depends on a previous “gradle assembleDebug” run.

  1. gradle clean cobertura -x generateCoberturaReport
  2. gradle robolectricTest
  3. gradle cobertura -x instrument -x copyCoberturaDatafile

The first Cobertura run will instrument all the classes, but not generate any reports. After that all Robolectric tests are run. Finally, the second Cobertura run will generate the coverage report.

I hope this helps you setting up Cobertura for your Android projects.

7 thoughts on “Robolectric and Cobertura with Gradle

  1. Actually, JC, if you are just starting to set up coverage reports for you Android project, I would have a look at JaCoCo. Since version 0.10.0 of the Android Gradle plugin, JaCoCo support has been added.
    This will remove some overhead of creating (and maintaining) your own Gradle scripts/tasks.

    There is an issue where JaCoCo doesn’t work when you use Dagger. The good thing is that Chris Jenkins already provided a workaround for it.

  2. Dear W.J.Warren,
    Would you have any of these gradle project files for download somewhere? I want to use Robolectric and Cobertera together using gradle. I found a template that lets me do it using maven but I want to use gradle as thats what most android projects seem to be using.

    Many thanks.

Leave a Reply

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