jcoverage Primer


jcoverage Primer

There are three ways to run jcoverage on your project: from the command-line, as an Ant script, or as a Maven plugin. We are going to cover how to run and interpret jcoverage reports as an Ant script and cover any issues with running it as a Maven plugin.

jcoverage as an Ant task

Adding jcoverage reports to your Ant buildfile is relatively easy. First you need to download the jcoverage/gpl JAR file and its third-party JAR files to your local hard drive. Place these files where your Ant project can find it typically this means that you can add it to your project's lib directory and reference it using your Ant buildfile (for more information about Ant, see Chapter 4). Once you have done that, you can add the JAR file to your build.xml:

 <path id="jcoverage.path">     <fileset dir="${lib.dir}">         <include name="jcoverage.jar"/>         <include name="log4j*.jar"/>         <include name="bcel.jar"/>         <include name="jakarta-oro*.jar"/>         <include name="java-getopt*.jar"/>     </fileset> </path> <taskdef classpath="jcoverage.path" resource="tasks.properties"/> 

This adds the following tasks to your Ant build file:

  • instrument: Instructs jcoverage what classes to add to the instrumentation and where to put the instrumented classes.

  • jtestrun: This will run your tests through jcoverage so that jcoverage can analyze the tests and their coverage.

  • report: Allows you to create custom reporting, such as xml and html.

  • merge: Allows you to merge multiple jcoverage runs together into one comprehensive report.

  • check: Specifies a pain threshold for coverage testing. If your project falls below a certain coverage percentage on either line or branch testing, check will fail and send up a red flag.

jcoverage puts all the information that it uncovers into a serialized file (.ser). You can specify additional files that can be merged together for different testing types (such as unit and functionality testing). In this way you create one comprehensive coverage report, instead of dealing with multiple ones.

Adding the Necessary Pieces to Your buildfile

Once you have added the jars as classpath references, you then add the taskdef element (as seen above). The next step is to make sure that you are running your JUnit tests correctly. This means that we need to instrument the classes first so that jcoverage can collect the information that it needs to build a report. This requires some setup first as we need to tell Ant where we want all the files to go first.

 <property name="build.dir" value="${basedir}/build/"/> <property name="build.classes.dir" value="${build.dir}/classes"/> <property name="build.test-classes.dir" value="${build.dir}/test-classes"/> <property name="build.instrumented-classes.dir" value="${build.dir}/instrumented-classes"/> <property name="build.coverage.dir" value="${build.dir}/coverage"/> <property name="build.reports.dir" value="${build.dir}/reports"/> <property name="lib.dir" value="${basedir}/lib"/> <property name="src.dir" value="${basedir}/src/java"/> <property name="test.dir" value="${basedir}/src/test"/> 

Here is a brief description of the properties shown above:

  • build.dir: The location we will build our application and tests to.

  • build.classes.dir: The location our main classes that get built compile to.

  • build-test-classes.dir: The location our test classes that get built compile to.

  • build-instrumented-classes.dir: The location our modified classes (application only, not test) get compiled to.

  • build.coverage.dir: The location our coverage reports that are created are sent to.

  • build.reports.dir: The location our test reports that are created are sent to.

  • lib.dir: The libraries directory; this is where jcoverage and other third-party JARs are placed.

  • src.dir: The java source directory.

  • test.dir: The test source directory.

Ok, so we have now defined all of our directories. Just like any build file we need to specify an init target that will create some of these directories that we need.

 <target name="init">     <mkdir dir="${build.dir}"/>     <mkdir dir="${build.classes.dir}"/>     <mkdir dir="${build.test-classes.dir}"/>     <mkdir dir="${build.coverage.dir}"/>     <mkdir dir="${build.instrumented-classes.dir}"/>     <mkdir dir="${build.reports.dir}"/> </target> 

Next we need to compile our source files and then instrument them.

 <target name="compile" description="compile all classes">     <javac srcdir="${src.dir}" destdir="${build.classes.dir}" failonerror="yes" debug="yes"/> </target> <target name="instrument" description="Add jcoverage instrumentation">     <instrument todir="${build.instrumented-classes.dir}">       <ignore regex="org.apache.log4j.*"/>       <fileset dir="${build.classes.dir}">         <include name="**/*.class"/>       </fileset>     </instrument> </target> 

This is fairly straightforward, but some explanation is warranted. First we call compile, which compiles the java files into class files. We then have the instrument target which calls its own task of instrument. The instrument task takes a todir argument to tell jcoverage where we wish to place the modified filesit's important that this be done to a separate directory as you don't want to distribute instrumented classes to your users (they are only meant for test coverage purposes). The body of the tag takes an Ant fileset specifying which classes to instrument. You can also specify packages to ignore using the ignore with a regex option; in this case we are telling jcoverage to ignore any line with a reference to log4j.

Now that we have instrumented our classes we want to run our unit tests on them.

 <target name="test" description="Unit test the application"> <javac srcdir="${test.dir}" destdir="${build.test-classes.dir}" failonerror="yes" debug="yes">  <classpath refid="junit"/>         <classpath location="${build.classes.dir}"/>     </javac> 

First we compile the test classes to the test-classes directory under build. Next we run the tests using junit. When running the tests we need to specify the instrumented classes prior to the real classes so that the instrumented classes are called first.

 <junit fork="yes" dir="${basedir}" errorProperty="test.failed" failureProperty="test.failed">       <!--         note the classpath order, instrumented classes are before the         original (uninstrumented) classes.       -->       <classpath refid="junit"/>       <classpath location="${build.instrumented-classes.dir}"/>       <classpath location="${build.classes.dir}"/>       <classpath location="${build.test-classes.dir}"/>       <!--         the instrumented classes reference classes used by the         jcoverage runtime.       -->       <classpath refid="jcoverage.path"/>       <formatter type="xml"/>       <test name="${testcase}" todir="${build.reports.dir}" if="testcase"/>       <batchtest todir="${build.reports.dir}" unless="testcase">                 <fileset dir="${build.test-classes.dir}">           <include name="**/*Test.class"/>         </fileset>       </batchtest>     </junit> </target> 

This executes a standard unit test, but because we are using the instrumented classes it requires that we have the jcoverage jars in the testing classpath; otherwise our tests will fail. Upon completion of the unit testing, jcoverage will have collected all of its data in jcoverage.ser, which it will then use to create the coverage reports:.

 <target name="coverage" description="HTML and XML coverage reports can be found in build/coverage">     <report srcdir="${src.dir}" destdir="${build.coverage.dir}"/>     <report srcdir="${src.dir}" destdir="${build.coverage.dir}" format="xml"/>     <echo> jcoverage reports have been generated. The HTML report is ${build.coverage.dir}/index.html The XML report is ${build.coverage.dir}/coverage.xml         </echo> </target> 

jcoverage creates two kind of reports: HTML and XML. In this example we specified that we want to see both. Now that we have built our reports, what do they look like? Here they arethe first figure shows the overall coverage report, and the second shows a class coverage report:

click to expand
click to expand

As you can see with our test class, we do not have 100% coverage, this is intentional to show what it looks when you don't have everything covered properly. We will examine what to do a little later in our case study.

jcoverage as a Maven Plugin

Installing the jcoverage Maven plugin is relatively easy; by default jcoverage is included as one of the optional plugins. If you want to use the latest jcoverage plugin, you will need to manually download it from http://maven.apache.org/reference/plugins/jcoverage/. Please follow the manual plugin installation instructions found in Chapter 26, Managing Projects with Maven of this book.

Once you have installed the plugin version you wish to use, you can set up jcoverage to be used in your Maven project. As with the Ant build file, there are a number of properties we can use to configure the plugin.

  • maven.jcoverage.dir: Specifies the root directory for the jcoverage report output and defaults to ${maven.build.dir}/jcoverage. This property should not need to be changed.

  • maven.jcoverage.instrumentation: Specifies where you would like the instrumented files to live and defaults to ${maven.jcoverage.dir}/classes, it also should not need to be changed.

  • maven.jcoverage.junit.fork: Specifies whether or not to fork junit into a separate JVM; it defaults to yes.

  • maven.jcoverage.merge.instrumentedFiles: Specifies the instrumented files list to be merged as a comma-seperated list. Necessary only if you have several types of unit testing that need one report.

  • maven.jcoverage.merge.outputDir: Specifies where the resulting jcoverage.ser file will be placed upon completion.

To call jcoverage you simply type

 maven jcoverage or jcoverage:html-report 

which will generate the HTML report that we saw above in the Ant section. To include this as one of the default reports for your project, you will need to add the following to the reports section of your Maven project.xml file:

 <report>maven-jcoverage-plugin</report> 

Now when you generate your Web site, this will automatically include the jcoverage reports for your project.




Professional Java Tools for Extreme Programming
Professional Java Tools for Extreme Programming: Ant, XDoclet, JUnit, Cactus, and Maven (Programmer to Programmer)
ISBN: 0764556177
EAN: 2147483647
Year: 2003
Pages: 228

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net