TDD Coverage of tests with JUnit Ant and Emma

4

Posted on September 23, 2011 by

Share it now!

Hello, good morning.

When we write out TDD tests we always care to write the right tests, and to be sure if we are testing all classes that we have. Imagine if you test 4 methods and forget to test a Catch of an Exception. How sad is that?

To help us with this problems there are some tools to cover your test; it will let you know where your test passed or missed.

I will talk about two coverage tests tools: Emma (our post today), Cobertura (the next post about TDD).

I will use the same code you can find in here (TDD with HSQLDB, JPA and Hibernate). If you want to set up your environment, follow that how-to and everything will work 100% for sure. Another post about TDD is: TDD – First Steps.

Today we will use the Emma framework with Ant. I do not have a good knowledge about Ant yet, so all the codes that I found on the internet maybe have some redundancies or something like that. Some day I will improve it.

Let us start downloading the libraries:

The JUnit library it is only used by the Emma Framework; it will not be necessary to add them in your project “Build Path”.

Create a file named “build.xml” at the root folder of your project (pay attention to the fact that your file must be in the root source of your project, or this script will fail):

Edit your file and add the code bellow:

<project name="Emma Reports" basedir=".">

    <!--  Project Source  Code -->
    <property name="src.dir" value="src" />
    <property name="bin.dir" value="bin" />
    <property name="teste.dir" value="src/test" />
    <property name="lib.dir" value="lib" />

    <!-- Emma source code -->
    <property name="emma.bin.dir" value="emma/bin" />
    <property name="emma.metadate.dir" value="emma/metadate" />
    <property name="emma.report.dir" value="emma/report" />

    <!-- Tested Class -->
    <property name="DogFacadeTest" value="test.com.facade.DogFacadeTest"/>

    <!-- Project classpath -->
    <path id="project.classpath">
        <pathelement location="${bin.dir}" />
        <fileset dir="${lib.dir}">
            <include name="*.jar" />
        </fileset>
    </path>

    <!-- Emma task definitions that you will find inside the jar -->
    <taskdef resource="emma_ant.properties">
        <classpath refid="project.classpath" />
    </taskdef>

    <!-- JUnit task definition -->
    <taskdef name="junit" classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask" />

</project>

In the “build.xml” file we are defining the script variables, the files path and the JUnit to be executed.

Go to the menu Window > Show View > Other. Type Ant and press Ok:


Drag the file “build.xml” and drop it into the Ant view. Double click in the file to execute it. You will see this message:

If you see the message “
Could not load definitions from resource emma_ant.properties. It could not be found.
” It is because your lib path is wrong. Check again your build.xml file is in the root of your project.

Do not go forward without solving this path issue.

Let us edit our “build.xml” and add the code to compile our java code. It has two actions (an action is defined as target):

    <!-- Clean UP Your Code -->
    <target name="01-CleanUp">
        <delete dir="${bin.dir}" />
        <mkdir dir="${bin.dir}" />
    </target>

    <!-- Compile Your Code -->
    <target name="02-CompileSourceCode" depends="01-CleanUp">
        <javac debug="on" srcdir="${src.dir}" destdir="${bin.dir}">
            <classpath refid="project.classpath" />
        </javac>
        <copy file="${src.dir}/META-INF/persistence.xml" todir="${bin.dir}/META-INF" />
    </target>

Notice that we have two actions named “01-CleanUp” and “02-CompileSourceCode”; to compile our code the target “depends” of the action that cleans the bin path; every time that you compile the source code of your project, the ant will run the action of cleaning the old code.

Let us create a task now with a word that you will hear a lot, Instrumentation. Just to comment about it, the Emma framework it is bytecode instrumented; Emma will not need adaptations or switches in the JVM to watch over your code. It will analyze your code through the bytecode only.

Edit your “build.xml” file and add the following task:

    <!-- Generate the Emma  -->
    <target name="03-Instrumentation" depends="02-CompileSourceCode">
        <emma>
            <instr instrpath="${bin.dir}" destdir="${emma.bin.dir}" metadatafile="${emma.metadate.dir}/metadate.emma" merge="false" mode="fullcopy" />
        </emma>
    </target>

Let us now add the target that will allow us to run the JUnit tests:

    <!-- Runs JUnit Tests -->
    <target name="04-RunTests" depends="03-Instrumentation">
        <junit haltonfailure="false" haltonerror="false" fork="true">
            <classpath>
                <pathelement location="${emma.bin.dir}/classes" />
                <pathelement location="${emma.bin.dir}/lib" />
                <path refid="project.classpath" />
            </classpath>
            <formatter type="plain" usefile="false" />
            <test name="${DogFacadeTest}" />
            <jvmarg value="-Demma.coverage.out.file=${emma.metadado.dir}/cobertura.emma" />
            <jvmarg value="-Demma.coverage.out.merge=false" />
        </junit>
    </target>

Run the test and you will see that in our code there is no error:

Let us create the task that will create the report:

    <!-- Creates the report -->
    <target name="00-GenerateReport" depends="04-RunTests">
        <delete dir="${emma.report.dir}" />
        <emma enabled="true">
            <report sourcepath="${src.dir}" sort="+block,+name,+method,+class" metrics="method:70,block:80,line:80,class:100">
                <fileset dir="${emma.metadate.dir}">
                    <include name="*.emma" />
                </fileset>
                <html outfile="${emma.report.dir}/report.html" depth="method" columns="name,class,method,block,line" />
            </report>
        </emma>
    </target>

Execute the task and then open the report file that you will find in: “
/emma/report/report.html
”.

As our last action, let us delete the files that were generated only to build the report and now they are not needed anymore. Edit the task that creates the report and add the line that will call the deleting files task:

    <!-- Creates the report -->
    <target name="00-GenerateReport" depends="04-RunTests">
        <delete dir="${emma.report.dir}" />
        <emma enabled="true">
            <report sourcepath="${src.dir}" sort="+block,+name,+method,+class" metrics="method:70,block:80,line:80,class:100">
                <fileset dir="${emma.metadate.dir}">
                    <include name="*.emma" />
                </fileset>
                <html outfile="${emma.report.dir}/report.html" depth="method" columns="name,class,method,block,line" />
            </report>
        </emma>

        <antcall target="05-DeleteOldReportData" />
    </target>

    <!-- Delete Old Report Data -->
    <target name="05-DeleteOldReportData">
        <delete dir="${emma.bin.dir}" />
        <delete dir="${emma.metadate.dir}" />
    </target>

Click here to download the source code of this tutorial.

I hope this post might help you.

If you have any doubt or comments to do, just post it.

See you later! \o_

PS.: Researched from:

Response to TDD Coverage of tests with JUnit Ant and Emma

  1. vinod

    nice explanation about emma..i need to know how to use emma ctl tool for the latest jar..
    when i tried i got this error:
    Exception in thread “main” java.lang.IllegalArgumentException: unknown command:
    [ctl]
    at com.vladium.emma.Command.create(Command.java:51)
    at emma.main(emma.java:39)
    at com.vladium.emma.ctl.ctlTask$commandElement.setArgs(ctlTask.java:48)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Current day month ye@r *