views:

5831

answers:

5

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

+4  A: 

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>
Rob Spieldenner
A: 

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&amp;release_id=336859

wheleph
+1  A: 

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>
matt b
A: 

How do I know instr and other dir's? I hate EMMA. Has no examples for a proj with src and test and 3rd party libs.

Ram
Anything in ${property} is wherever you or your standard chooses to put them.
Rob Spieldenner
Also updated my original answer
Rob Spieldenner
A: 

Hi,

How Can I instrument Jar file using EMMA+ANT ..Any Example?

Following Script is not working for Jar files...

<emma enabled="${emma.enabled}" >
     <instr instrpath="${jar.location}"
         destdir="${inst.jar.location}" 
         metadatafile="${inst.jar.location}/metadata.emma"
         merge="true"
      mode="overwrite"
    />
</emma>
Rajesh