Code coverage is important as it gives developers confidence in the code that they are checking in. And for a startup automated test and measuring code coverage is equally important to be able to Ship early and be nimble. I recently automated unit testing in jenkins and wanted to measure how much code coverage we have. So I integrated cobertura in the build framework. Cobertura is a build time instrumentation plugin so the steps are:
1) compile the code
2) Instrument the classes to generate instrumented classes with cobertura hooks.
3) modify junit class path to put instrumented classes before real classes
4) add a system property in junit ant task, so that cobertura knows where to write its statistics.
5) generate a coverage report in html to be used by developers
6) generate a coverage report in xml so that it can be published to sonar so we can do trends on code coverage release after release.
Here is how a typical code coverage report looks like http://cobertura.sourceforge.net/sample/
Here are some more details on the steps:
<target name="instrument" description="Run Tests">
<delete file="${basedir}/cobertura.ser" />
<delete dir="${basedir}/build/instrumented-classes" />
<cobertura-instrument todir="${basedir}/build/instrumented-classes">
<ignore regex="org.apache.log4j.*" />
<fileset dir="${basedir}/build/classes">
<include name="**/*.class" />
<exclude name="**/*Test.class" />
</fileset>
</cobertura-instrument>
</target>
<junit tempdir="${basedir}/build" printsummary="on"
fork="yes"
forkmode="perBatch"
haltonfailure="true"
failureproperty="tests.failed"
showoutput="false">
<jvmarg value="-Djava.awt.headless=true"/>
<jvmarg value="-Djava.io.tmpdir=${basedir}/build/jenkinstest"/>
<jvmarg value="-Dnet.sourceforge.cobertura.datafile=${basedir}/cobertura.ser" />
<classpath location="build/instrumented-classes" />
<classpath refid="${testClasspathRefId}"/>
<classpath refid="cobertura.classpath" />
<formatter type="plain" usefile="false"/>
<batchtest todir="${basedir}/${testReportsDir}">
<fileset dir="${basedir}/${build}/classes">
<include name="**/*${testClassPattern}.*"/>
<exclude name="**/*$*.*"/>
</fileset>
<formatter type="xml"/>
</batchtest>
</junit>
<target name="coverage">
<delete file="build/cobertura.ser" quiet="true" />
<delete dir="build/coverage" quiet="true"/>
<cobertura-merge datafile= "build/cobertura.ser">
<fileset dir="${basedir}/">
<include name="**/cobertura.ser"/>
</fileset>
</cobertura-merge>
<cobertura-report format="html" destdir="build/coverage" datafile= "build/cobertura.ser">
<fileset dir="${basedir}" includes="**/*.java"/>
</cobertura-report>
<cobertura-report format="xml" destdir="build/coverage" datafile= "build/cobertura.ser">
<fileset dir="${basedir}" includes="**/*.java"/>
</cobertura-report>
<cobertura-check haltonfailure="false" />
</target>
1) compile the code
2) Instrument the classes to generate instrumented classes with cobertura hooks.
3) modify junit class path to put instrumented classes before real classes
4) add a system property in junit ant task, so that cobertura knows where to write its statistics.
5) generate a coverage report in html to be used by developers
6) generate a coverage report in xml so that it can be published to sonar so we can do trends on code coverage release after release.
Here is how a typical code coverage report looks like http://cobertura.sourceforge.net/sample/
Here are some more details on the steps:
<target name="instrument" description="Run Tests">
<delete file="${basedir}/cobertura.ser" />
<delete dir="${basedir}/build/instrumented-classes" />
<cobertura-instrument todir="${basedir}/build/instrumented-classes">
<ignore regex="org.apache.log4j.*" />
<fileset dir="${basedir}/build/classes">
<include name="**/*.class" />
<exclude name="**/*Test.class" />
</fileset>
</cobertura-instrument>
</target>
<junit tempdir="${basedir}/build" printsummary="on"
fork="yes"
forkmode="perBatch"
haltonfailure="true"
failureproperty="tests.failed"
showoutput="false">
<jvmarg value="-Djava.awt.headless=true"/>
<jvmarg value="-Djava.io.tmpdir=${basedir}/build/jenkinstest"/>
<jvmarg value="-Dnet.sourceforge.cobertura.datafile=${basedir}/cobertura.ser" />
<classpath location="build/instrumented-classes" />
<classpath refid="${testClasspathRefId}"/>
<classpath refid="cobertura.classpath" />
<formatter type="plain" usefile="false"/>
<batchtest todir="${basedir}/${testReportsDir}">
<fileset dir="${basedir}/${build}/classes">
<include name="**/*${testClassPattern}.*"/>
<exclude name="**/*$*.*"/>
</fileset>
<formatter type="xml"/>
</batchtest>
</junit>
<target name="coverage">
<delete file="build/cobertura.ser" quiet="true" />
<delete dir="build/coverage" quiet="true"/>
<cobertura-merge datafile= "build/cobertura.ser">
<fileset dir="${basedir}/">
<include name="**/cobertura.ser"/>
</fileset>
</cobertura-merge>
<cobertura-report format="html" destdir="build/coverage" datafile= "build/cobertura.ser">
<fileset dir="${basedir}" includes="**/*.java"/>
</cobertura-report>
<cobertura-report format="xml" destdir="build/coverage" datafile= "build/cobertura.ser">
<fileset dir="${basedir}" includes="**/*.java"/>
</cobertura-report>
<cobertura-check haltonfailure="false" />
</target>
Comments
Post a Comment