Question

How do I setup an Ant task to generate Emma code coverage reports?

Was it helpful?

Solution

To answer questions about where the source and instrumented directories are (these can be switched to whatever your standard directory structure is):

<property file="build.properties" />
<property name="source" location="src/main/java" />
<property name="test.source" location="src/test/java" />
<property name="target.dir" location="target" />
<property name="target" location="${target.dir}/classes" />
<property name="test.target" location="${target.dir}/test-classes" />
<property name="instr.target" location="${target.dir}/instr-classes" />

Classpaths:

<path id="compile.classpath">
  <fileset dir="lib/main">
    <include name="*.jar" />
  </fileset>
</path>

<path id="test.compile.classpath">
  <path refid="compile.classpath" />
  <pathelement location="lib/test/junit-4.6.jar" />
  <pathelement location="${target}" />
</path>

<path id="junit.classpath">
  <path refid="test.compile.classpath" />
  <pathelement location="${test.target}" />
</path>

First you need to setup where Ant can find the Emma libraries:

<path id="emma.lib" >
    <pathelement location="${emma.dir}/emma.jar" />
    <pathelement location="${emma.dir}/emma_ant.jar" />
</path>

Then import the task:

<taskdef resource="emma_ant.properties" classpathref="emma.lib" />

Then instrument the code:

<target name="coverage.instrumentation">
    <mkdir dir="${instr.target}"/>
    <mkdir dir="${coverage}"/>
    <emma>
        <instr instrpath="${target}" destdir="${instr.target}" metadatafile="${coverage}/metadata.emma" mode="copy">
            <filter excludes="*Test*"/>
        </instr>
    </emma>
    <!-- Update the that will run the instrumented code -->
    <path id="test.classpath">
        <pathelement location="${instr.target}"/>
        <path refid="junit.classpath"/>
        <pathelement location="${emma.dir}/emma.jar"/>
    </path>
</target>

Then run a target with the proper VM arguments like:

<jvmarg value="-Demma.coverage.out.file=${coverage}/coverage.emma" />
<jvmarg value="-Demma.coverage.out.merge=true" />

Finally generate your report:

<target name="coverage.report" depends="coverage.instrumentation">
    <emma>
        <report sourcepath="${source}" depth="method">
            <fileset dir="${coverage}" >
                <include name="*.emma" />
            </fileset>
            <html outfile="${coverage}/coverage.html" />
        </report>
    </emma>
</target>

OTHER TIPS

The User Guide has a good example of how to set up your build script so that you not only seperate the instrumented code from the execution, but it's also all contained in the same <target> so that you don't have to run a series of different targets, but instead you can just do something like ant emma tests (if ant tests was how you normally ran your unit tests, for example).

Here's their example:

<target name="emma" description="turns on EMMA instrumentation/reporting" >
    <property name="emma.enabled" value="true" />
    <!-- EMMA instr class output directory: -->
    <property name="out.instr.dir" value="${basedir}/outinstr" />
    <mkdir dir="${out.instr.dir}" />
</target>

<target name="run" depends="init, compile" description="runs the examples" >
    <emma enabled="${emma.enabled}" >
      <instr instrpathref="run.classpath"
             destdir="${out.instr.dir}" 
             metadatafile="${coverage.dir}/metadata.emma"
             merge="true"
      />
    </emma>

    <!-- note from matt b: you could just as easily have a <junit> task here! -->
    <java classname="Main" fork="true" >
      <classpath>
       <pathelement location="${out.instr.dir}" />
        <path refid="run.classpath" />
        <path refid="emma.lib" />
      </classpath> 
      <jvmarg value="-Demma.coverage.out.file=${coverage.dir}/coverage.emma" />
      <jvmarg value="-Demma.coverage.out.merge=true" />
    </java>

    <emma enabled="${emma.enabled}" >
      <report sourcepath="${src.dir}" >
        <fileset dir="${coverage.dir}" >
          <include name="*.emma" />
        </fileset>

        <txt outfile="${coverage.dir}/coverage.txt" />
        <html outfile="${coverage.dir}/coverage.html" />
      </report>
    </emma>
</target>

Emma 2.1 introduces another way of obtaining runtime coverage information (.ec file). One can remotely request the data from the given port of the computer where an instrumented application is runnig. So there's no need to stop VM.

To get the file with runtime coverage data you need to insert the following snippet in your Ant script between running of your tests and generating coverage report:

<emma>
    <ctl connect="${emma.rt.host}:${emma.rt.port}" >
        <command name="coverage.get" args="${emma.ec.file}" />
        <command name="coverage.reset" />
    </ctl>
</emma>

Other steps are similar to Emma 2.0. They are perfectly described in previous post

More information on Emma 2.1 features: http://sourceforge.net/project/shownotes.php?group_id=108932&release_id=336859

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top