Piotr Gabryanczyk’s Blog

Java, Refactoring, AOP, Spring, DDD, TDD, etc.

  • Blogroll

    • I have joined Anti-IF Campaign

Gradle Cobertura Integration Revisited

Posted by Piotr Gabryanczyk on April 17, 2010

Problem

I’d like to run cobertura coverage report using gradle in a non intrusive way similar to maven.
I just want to do this:

gradle cobertura


and in my script:

apply from: 'cobertura.gradle'

Current solution

There is a great solution to this problem here. It works, but is not as unintrusive and not as easy to use as I would like it to be.

My solution

This works for Gradle version 0.9-preview-1.

cobertura.gradle:

logger.info "Configuring Cobertura Plugin"

configurations{
  coberturaRuntime {extendsFrom testRuntime}
}

dependencies {
  coberturaRuntime 'net.sourceforge.cobertura:cobertura:1.9.3'
}

def serFile="${project.buildDir}/cobertura.ser"
def classes="${project.sourceSets.main.classesDir}"
def classesCopy="${classes}-copy"


task cobertura(type: Test){
  dependencies {
    testRuntime 'net.sourceforge.cobertura:cobertura:1.9.3'
  }  

  systemProperties["net.sourceforge.cobertura.datafile"] = serFile
}

cobertura.doFirst  {
  logger.quiet "Instrumenting classes for Cobertura"
  ant {
    delete(file:serFile, failonerror:false)
    delete(dir: classesCopy, failonerror:false)    
    copy(todir: classesCopy) { fileset(dir: classes) }

    taskdef(resource:'tasks.properties', classpath: configurations.coberturaRuntime.asPath)
    'cobertura-instrument'(datafile: serFile) {
      fileset(dir: classes,
              includes:"**/*.class",
              excludes:"**/*Test.class")
    }
  }
}

cobertura.doLast{
  if (new File(classesCopy).exists()) {
    ant.'cobertura-report'(destdir:"${project.reportsDir}/cobertura",
            format:'html', srcdir:"src/main/java", datafile: serFile)

    ant.delete(file: classes)
    ant.move(file: classesCopy, tofile: classes)
  }
}


And then your build.gradle could look like that:

apply plugin: 'java'
apply from: 'cobertura.gradle'
...

Advertisements

4 Responses to “Gradle Cobertura Integration Revisited”

  1. Kishen said

    Hi!

    Thank you for your post.

    But I seem to get the following error while running the task:

    Cause: Error validating task ‘:api:cobertura’: No value has been specified for property ‘classpath’.
    @ line: taskdef(resource:’tasks.properties’, classpath: configurations.coberturaRuntime.asPath)

    Any idea what went wrong?

    Thanks!

  2. Stian said

    Kishen!

    This example is not complete. To make a task of type Test, you have to set the following:


    task intTest(type: Test) {
    testClassesDir = sourceSets.intTest.classesDir
    classpath = sourceSets.intTest.runtimeClasspath
    }

    This code is found at http://www.gradle.org/0.9-rc-1/docs/userguide/userguide_single.html#sec:source_sets

  3. It is sufficient to place the instrumented class files at the start of the test runtime classpath, like this:

    sourceSets {
    // place your instrumented classes at the FRONT of the list of TEST runtime
    // dependencies (including the original compiled project classes ) so that they get preference at test time
    runtimeClasspath = configurations.instrumentation + runtimeClasspath
    }

    Then you don’t need to copy files around

  4. GC said

    Hi Piotr,

    I am new to Gradle, Can you please suggest how to in force minimum coverage.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: