I am using sonar to measure code quality. One thing that I do not know is the steps to measure code coverage using Cobertura.

I followed the steps from http://cobertura.sourceforge.net/anttaskreference.html and was able to generate xml files. How do I get these xml files into SONAR?

Is there an easier way to use Cobertura in SONAR?

I am running the code coverage (Cobertura) in a different server than my SONAR server. Both servers are running under LINUX.

Thanks for the help!

upvote
  flag
Update on this topic: examples can be found on our sonar-example repository => github.com/SonarSource/sonar-examples/tree/master/projects/… – Fabrice - SonarSource Team

3 Answers 11

You would have to add these properties to Sonar's pom.xml:

<properties>
    <sonar.dynamicAnalysis>false</sonar.dynamicAnalysis>
    <sonar.phase>generate-sources</sonar.phase>
    <sonar.surefire.reportsPath>target/reports/test/</sonar.surefire.reportsPath>
    <sonar.cobertura.reportPath>../project/target/reports/coverage/coverage.xml</sonar.cobertura.reportPath>
</properties>

(with paths appropriate to your environment)

And run:

mvn sonar:sonar

Check the user list for more details.

upvote
  flag
What if my project does not use Maven? Do I still need to run it? From Cobertura website, it looks like we can also use ANT. Am I wrong? Right now, I am confused with the relationship between sonar - maven - Cobertura. Let's say I invoke a build from hudson by calling ant that will run my build script. My build script will do a build and also update SONAR DB. Furthermore, originally, I thought I just need to add some commands in my build script that will run Coberture. Now I am not sure. How should I invoke Coberture with maven in my case? Other solution is also welcomed?Thanks for your help. – lwijono
upvote
  flag
Sonar was coupled to Maven until recently. Since 2.6 (March 2011), Sonar also supports ANT. You can add the properties above to the ant script as shown here, for example: <property key="sonar.dynamicAnalysis" value="false" />. I have not run Sonar + Cobertura + Ant runner, but it should not be any different. Alternatively, you can check out a Sonar Stand Alone ( no ANT, Maven, etc. ) runner – tolitius

if you're using Maven, then you do not have anything special to specify in your POM file. Just run "mvn clean sonar:sonar" and Sonar will automatically compile your code, run your tests with Cobertura (which is the default coverage engine in Sonar) and push all the results in the DB.

Same if you're using Ant [1] or the simple java runner [2] instead of Maven.

I do insist on the fact that you do not have to manually run Cobertura (with an Ant task for instance) previously to running Sonar.

[1] http://docs.codehaus.org/display/SONAR/Analyzing+with+Sonar+Ant+Task

[2] http://docs.codehaus.org/display/SONAR/Analyse+with+a+simple+Java+Runner

Fabrice, SonarSource

up vote 11 down vote accepted

You configure the Sonar task to upload unit test and cobertura reports generated by other parts of your build logic.

This is in contrast to Maven which has a standard build life-cycle that Sonar is able to leverage.

Unit test and code coverage

The following logic runs the unit tests with cobertura instrumented classes. An XML coverage report is generated by cobertura at the end:

<target name="instrument-classes" depends="compile-tests">
    <taskdef resource="tasks.properties" classpathref="test.path"/>
    <cobertura-instrument todir="${instrumented.classes.dir}" datafile="${build.dir}/cobertura.ser">
        <fileset dir="${classes.dir}"/>
    </cobertura-instrument>
</target>

<target name="junit" depends="instrument-classes">
    <junit printsummary="yes" haltonfailure="yes">
        <classpath>
            <path refid="test.path"/>
            <pathelement path="${instrumented.classes.dir}"/>
            <pathelement path="${test.classes.dir}"/>
        </classpath>

        <formatter type="xml"/>

        <batchtest fork="yes" todir="${test.reports.dir}">
            <fileset dir="${test.src.dir}">
                <include name="**/*Test*.java"/>
                <exclude name="**/AllTests.java"/>
            </fileset>
        </batchtest>
    </junit>
</target>

<target name="test" depends="junit">
    <cobertura-report format="xml" datafile="${build.dir}/cobertura.ser" destdir="${cobertura.reports.dir}"/> 
</target>

Invoking Sonar

I normally use a very simple Sonar target:

<target name="sonar" depends="test">
    <taskdef uri="antlib:org.sonar.ant" resource="org/sonar/ant/antlib.xml" classpathref="sonar.path"/>

    <sonar:sonar key="${sonar.project.key}" version="${sonar.project.version}" xmlns:sonar="antlib:org.sonar.ant"/>
</target>

And use a properties file to control all aspects of Sonar's behaviour:

sonar.project.key=org.demo:demo
sonar.project.version=1.0-SNAPSHOT
sonar.projectName=Demo project

sonar.host.url=http://myserver:9000
sonar.jdbc.url=jdbc:mysql://myserver:3306/sonar?useUnicode=true&characterEncoding=utf8
sonar.jdbc.driverClassName=com.mysql.jdbc.Driver
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar

sonar.sources=${src.dir}
sonar.tests=${test.src.dir}
sonar.binaries=${classes.dir}

sonar.dynamicAnalysis=reuseReports
sonar.surefire.reportsPath=${test.reports.dir}
sonar.java.coveragePlugin=cobertura
sonar.cobertura.reportsPath=${cobertura.reports.dir}/coverage.xml

Demonstrates how Sonar can be configured to pick up the unit test reports created by junit and the code coverage report generated by cobertura.

The build does not have to run on the same server as Sonar. In that case one must provide the remote Sonar URL and JDBC credentials.

upvote
  flag
I tried to follow your instruction; however, I still have the same problem as before, I cannot see the coverage statistic inside SONAR. The xml and the ser files generated are similar to what I had previously. Can you help me getting the statistic in SONAR works? – lwijono
upvote
  flag
Does the Sonar task output show that you're loading the correct coverage file? – Mark O'Connor
upvote
  flag
How do I check this? – lwijono
upvote
  flag
Have you configured the "sonar.cobertura.reportsPath" property to pick up the correct file? The task output should display the full file path. If Sonar is attempting to load a non-existent file this would explain your missing code coverage metrics – Mark O'Connor
upvote
  flag
Yes, I have. I think I have got it to work. What confuses me previously was because I see 0% on the test coverage, so I thought I may have not configure it properly. Later on, I realized that if sonar was not configured properly, it gave me just "-". Thanks for your help. Btw, I like the way you organize the sonar configuration parameters. Now I need to figure out why it gave me 0% coverage. – lwijono
2 upvote
  flag
In later releases, the 'sonar.cobertura.reportsPath' property has changed to 'sonar.cobertura.reportPath' > docs.codehaus.org/display/SONAR/Advanced+parameters. – Timoteo Ponce
upvote
  flag
Another change in property names: prior to Sonar 3.3 the property to activate cobertura was sonar.core.codeCoveragePlugin. see docs.codehaus.org/display/SONAR/… – Stefan Haberl

Not the answer you're looking for? Browse other questions tagged or ask your own question.