Gradle 1.6 jacoco in multi module build


(Mikael Andersson) #1

Hi

How do I use jacoco plugin with a multi module build in order to produce one jacoco xml output file (and report) containing the coverage for all subprojects?

Also I found I had to add updated the jacocoClasspath like this: jacocoClasspath += files(

“…/lib/org.jacoco.core-${jacoco.toolVersion}.jar”,

“…/lib/org.jacoco.report-${jacoco.toolVersion}.jar”,

“…/lib/asm-all-4.0.jar”

) Is that necessary or have I missed a configuration step?

Cheers,

micke


(Mikael Andersson) #2

Managed to get it working.

Feels like a bit of a hack, especially having to manually add jars to the classpath.

Is there a better way of integrating jacoco into a multi-module project?

subprojects{
 apply plugin: "jacoco"
 apply plugin:'java'
 apply plugin:'eclipse'
   group='testing'
 version='0.4-SNAPSHOT'
    jacoco {
  toolVersion = "0.6.2.201302030002"
 }
 jacocoTestReport{
     jacocoClasspath += files(
   "../lib/org.jacoco.core-${jacoco.toolVersion}.jar",
   "../lib/org.jacoco.report-${jacoco.toolVersion}.jar",
   "../lib/asm-all-4.0.jar"
   )
  reports {
   xml.enabled false
   csv.enabled false
   html.enabled false
  }
 }
 repositories {
  flatDir(dirs: file('../lib'))
 }
    dependencies {
  testCompile 'junit:junit-4.7@jar'
 }
  }
  task jacocoMerge(type:JacocoMerge){
 jacocoClasspath += files(
  "lib/org.jacoco.core-${jacoco.toolVersion}.jar",
  "lib/org.jacoco.report-${jacoco.toolVersion}.jar",
  "lib/asm-all-4.0.jar"
  )
 def tmpTasks = []
 subprojects.each{
  dependsOn << it.tasks.withType(Test)
 }
 subprojects.each{
  tmpTasks << it.tasks.withType(JacocoReport)
 }
 dependsOn tmpTasks
 executionData(tmpTasks)
}
  task jacocoReport(type:JacocoReport){
 dependsOn(jacocoMerge)
 jacocoClasspath += files(
  "lib/org.jacoco.core-${jacoco.toolVersion}.jar",
  "lib/org.jacoco.report-${jacoco.toolVersion}.jar",
  "lib/asm-all-4.0.jar"
  )
 reports {
   xml{
    enabled true
    destination "${buildDir}/reports/jacoco/jacoco.xml"
   }
   csv.enabled false
   html{
    enabled true
    destination "${buildDir}/reports/jacoco/jacocoHtml"
   }
 }
    def tmpTasks = []
 def tmpSourceSets = []
 subprojects.each{
  tmpTasks << it.tasks.withType(JacocoReport)
  tmpSourceSets << it.sourceSets.main
 }
    executionData(tmpTasks)
 tmpSourceSets.each{
  sourceSets(it)
 }
}

Many thanks,

Micke


(Matthew Rusinak) #3

Related to this, as of 1.7, one must still set jacocoClasspath on custom JacocReport tasks, which is quite sad. As for the original question, if you don’t care about having the merged binary data file, you can simplify your gradle script a bit:

subprojects {
    apply plugin: "java"
    apply plugin: "jacoco"
          test {
        // Don't instrument and generate code coverage unless "-Pcodecoverage" is set on the command line
        jacoco {
            enabled = project.hasProperty("codecoverage")
        }
    }
}
  configurations {
    jacoco {
        description "JARs required for doing our own JacocoReport tasks"
    }
}
  dependencies {
    jacoco 'org.jacoco:org.jacoco.ant:0.6.2.201302030002'
}
  task jacocoReport(type: JacocoReport) {
    jacocoClasspath = configurations.jacoco
      // Add execution data from all subprojects
    executionData fileTree(project.rootDir.absolutePath).include("*/build/jacoco/*.exec")
      // Add source classes from all subprojects
    subprojects.each {
        sourceSets it.sourceSets.main
    }
      // Make the aggregate report go in a top-level directory somewhere
    reports {
        html {
            enabled true
            destination "release/reports/jacoco"
        }
    }
}