Daniel Doubrovkine bio photo

Daniel Doubrovkine

aka dB., @awscloud, former CTO @artsy, +@vestris, NYC

Email Twitter LinkedIn Github Strava
Creative Commons License

I’ve written an unusually high number of unit tests for the Java portion of Waffle, mostly because the project became popular really fast with all those Java people trying to do Windows authentication. Some have succeeded and some filed several rather complicated bug reports that dealt with concurrency, sessions across HTTP requests, etc. It all needed to be unit-tested in order to make industrial-grade software.

If you asked me yesterday, I would have said that Waffle unit tests cover 99% of the code. But Emma says otherwise, and it’s probably right.

Running Emma with JUnit

It took me half an hour to integrate Emma. Pretty easy. You should do it too.

I downloaded Emma from https://emma.sourceforge.net and added it to ThirdParty/emma. What I want next is a cover target that can execute all unit tests with code coverage. We’re doing this in ANT with JUnit.

Define Emma JARs Location and ClassPath

<property name="emma.dir" value="${thirdparty.dir}/emma/lib" />
<path id="emma.classpath" >
  <fileset dir="${thirdparty.dir}/emma/lib">
    <include name="emma.jar" />
    <include name="emma_ant.jar" />
  </fileset>
</path>

Instrument Files

I went the route of not changing my build tasks and instrumenting the .class files already built. Then I swap in those files with the instrumented ones. Note that Emma only generates .class files for instrumentable classes – those not containing debugging information, interface definitions and such aren’t included.

<target name="instrument">
  <echo message="Instrumenting ${waffle.lib}" />
  <path id="build.classpath">
    <pathelement path="${waffle.lib}"/>
  </path>
  <emma>
    <instr instrpathref="build.classpath" destdir="${waffle.cover}/lib"
              metadatafile="${waffle.cover}/metadata.emma" merge="true" />
  </emma>
  <copy todir="${waffle.lib}">
    <fileset dir="${waffle.cover}/lib" includes="**/*" />
  </copy>
</target>

Running Tests

The tests are run the same way as before, but we need to tell Emma where to write its output.

<junit ...
  <jvmarg value="-Demma.coverage.out.file=${waffle.cover}/coverage.emma" />
</junit>

Generating an EMMA Report

Finally, we want to get a nice HTML document that summarizes coverage.

<target name="cover-report">
    <emma>
        <report sourcepath="${waffle.src}">
            <fileset dir="${waffle.cover}">
                <include name="*.emma" />
            </fileset>
            <html outfile="${waffle.cover}/coverage.html" />
        </report>
    </emma>
</target>

Here’s an output.

I see a lot of red. Emma doesn’t think I am doing such a great job after-all.