Gradle Glam: jacoco + coveralls - No Fluff Just Stuff

Gradle Glam: jacoco + coveralls

Posted by: Andres Almiray on July 23, 2014

Welcome to another installment of Gradle Glam! This time I'd like to say a few words about the jacoco in combination with coveralls. JaCoCo is a well-known code coverage tool; many prefer it over Cobertura because JaCoCo delivers a much more detailed code coverage.

coveralls.io is a cloud based service that keeps track of code coverage produced by continues integration services, such as Travis-CI. What's great about this service is that it keeps historical records of all coverage sessions. Integrating both jacoco and coveralls in a gradle build is quite simple; you just need to make sure the jacocoTestReport task has the XML report enabled. This configuration works out of the box when your build defines a single project, but it breaks down the moment you try it on a multi-project build. Why? Simply put, coveralls expect an aggregated coverage report and jacoco will not do it for you out of the box.

Here's how you can make it happen.

First, make sure that the jacoco plugin is applied to all projects, including the root project (even if it's just an umbrella project, i.e, one that does not produce artifacts by itself). Next, enable the XML report on the jacocoTestReport task of each subproject. Finally, back on the root project, create a new task of type org.gradle.testing.jacoco.tasks.JacocoReport that's aware of the configuration of the jacocoTestReport tasks found in each subproject. You'll end up with something looking like this

The trick is for the jacocoRootReport to declare a dependency on the test task from all subprojects. It also adjusts the values of sourceDirectories, classDirectories and executionData properties in such a way that they depend on each subproject too.

Assuming the following project structure is in place

Running the jacocoRootReport task at the root project level yields the following

full coverage

As you can appreciate all sources have been covered and aggregated. This approach has one drawback, chiefly that every subproject must produce a coverage execution data file. This only happens when tests are run. What if a project does not have tests? The root report will be skipped altogether <sad-panda-face/>. The quick workaround is to make sure there's at least one test that can be run, even if it's ignored, like the following one

Rerunning the jacocoRootReport task now yields the following report

partial coverage

Now we're back in business :-D The final piece of the puzzle is activating coveralls when running on the CI environment. Here's an example for Travis-CI:

And that's how it's done.

Keep on Groovying!

Andres Almiray

About Andres Almiray

Andres is a Java/Groovy developer and a Java Champion with more than 20 years of experience in software design and development. He has been involved in web and desktop application development since the early days of Java. Andres is a true believer in open source and has participated on popular projects like Groovy, Griffon, and DbUnit, as well as starting his own projects (Json-lib, EZMorph, GraphicsBuilder, JideBuilder). Founding member of the Griffon framework and Hackergarten community event. https://ch.linkedin.com/in/aalmiray

Why Attend the NFJS Tour?

  • » Cutting-Edge Technologies
  • » Agile Practices
  • » Peer Exchange

Current Topics:

  • Languages on the JVM: Scala, Groovy, Clojure
  • Enterprise Java
  • Core Java, Java 8
  • Agility
  • Testing: Geb, Spock, Easyb
  • REST
  • NoSQL: MongoDB, Cassandra
  • Hadoop
  • Spring 4
  • Cloud
  • Automation Tools: Gradle, Git, Jenkins, Sonar
  • HTML5, CSS3, AngularJS, jQuery, Usability
  • Mobile Apps - iPhone and Android
  • More...
Learn More »