Saturday, September 29, 2012

Code Coverage in ADF with EMMA

If you have a requirement for doing code coverage in an ADF application you can easily accomplish it using EMMA. The good thing about EMMA is that it supports offline instrumentation which essentially helps in collecting and merging the data from various runs plus in case of offline instrumentation you are not affected by the runtime class loading behavior of the application container. The concept in brief is to have the compiled classes with byte-code instrumentation done by EMMA and then later post you run your use cases you can merge the coverage data with the class metadata and generate the report regarding the code coverage done during testing.
The steps to accomplish it for your ADF app are simple.
  1. Just create an ant build file for each of your projects i.e one for your model project and the other for your view project. Also make sure that you select the ojdeploy tasks while doing so for your view controller project. build
  2. Now add the emma ant task for generating the class metadata for each of your projects. The following snippet shows the relevant ant tasks for the ViewController project.
    <property file="build1.properties"/>
    <path id='emma.lib' >
    <pathelement location="${emma.dir}/emma.jar"/>
    <pathelement location="${emma.dir}/emma_ant.jar"/>
    </path>
    <taskdef resource="emma_ant.properties" classpathref="emma.lib"/>
    <target name="init">
    <tstamp/>
    <mkdir dir="${output.dir}"/>
    <mkdir dir="${coverage.dir}"/>
    <mkdir dir="${instrumentation.dir}"/>
    </target>
    <target name="emma" description="turns on EMMA instrumentation/reporting" >
    <!-- EMMA instr class output directory: -->
    <property name="emma.enabled" value="true" />
    <property name="out.instr.dir" value="outinstr" />
    <mkdir dir="${out.instr.dir}" />
    </target>
    <target name="emmabuild" depends="clean,init,compile,emma,copy" description="runs the examples" >
    <emma enabled="${emma.enabled}" >
    <instr merge="yes" filter="com.blogspot.*" destdir="${instrumentation.dir}" instrpath="${output.dir}" mode="copy"/>
    </emma>
    </target>
    <target name="instrumentView" description="Copy instrumented classes to output directory"
    depends="emmabuild">

    <patternset id="copy1.patterns">
    <include name="**/*.class"/>
    </patternset>
    <copy todir="${output.dir}">
    <fileset dir="${instrumentation.dir}">
    <patternset refid="copy1.patterns"/>
    </fileset>
    </copy>
    </target>

    As can be seen from the above snippet EMMA provides you with filtering capabilities so that you can select the classes that you want to be part of the instrumented build.


  3. The following snippet shows the relevant snippet from ojdeploy task
    <target name="deploy" description="Deploy JDeveloper profiles"
    depends="instrumentView">
    .........
    ..........

    <ora:deploy>
    <ora:parameter name="workspace"
    value="${oracle.jdeveloper.workspace.path}"/>
    <parameter name="nodatasources" value="true"/>
    <parameter name="forcerewrite" value="true"/>
    <ora:parameter name="profile"
    value="${oracle.jdeveloper.deploy.profile.name}"/>
    <ora:parameter name="nocompile" value="true"/>
    <ora:parameter name="outputfile"
    value="${oracle.jdeveloper.deploy.outputfile}"/>
    </ora:deploy>
    </target>

    Notice the nocompile option is set to true because we do not want the ojdeploy build task to overwrite the instrumented classes.


  4. Also i have added the following snippet to the copy task so that the page definitions are also included in the ear that is going to be generated
    <fileset dir="adfmsrc">
    <patternset refid="copy.patterns"/>
    </fileset>



  5. Now to build the project just run the ant task instrumentModel followed by the deploy task and you will have the ear file with instrumented build. Also you will have class metadata file coverage.em generated for each of your projects (rename either one as coverage1.em)


  6. Place only the emma.jar into lib/ext directory of the jre used by your weblogic server.


  7. Start the weblogic server, deploy the generated ear file and run through a flow and shutdown the server, you will see in the logs the location of generated coverage file (coverage.ec)


  8. Place all the three files in one directory (only for ease of use) and run the following command to generate the html report showing the code coverage done while executing your flow.



    java emma report -report html,txt -in "C:/emmareport/coverage.em" -in "C:/emmareport/coverage1.em" -in "C:/emmareport/coverage.ec" -Dreport.html.out.file="C:/emmareport/coverage.html" 

    Sample images of the report are shown below.


The sample application can be downloaded from here.