Skip to main content

Integrating the JaCoCo code coverage plugin into a Java Maven project for unit testing with testng



I’ll show how to do this for both offline instrumentation and for using the JaCoCo runtime agent.

It is very easy because you don’t need to change the usual way of writing your tests. Its only a matter of changing the pom.xml file in your maven project.

1. JaCoCo code coverage with JaCoCo runtime agent

Since we use testng for unit test writing, we put the following dependency under dependencies.

    <dependencies>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>${testng.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>



Then under build, we first need to have the JaCoCo plugin put under the plugins section of your project pom.xml. (Note - this is the parent pom we are referring to) This plugin configuration will also contain 2 executions, one required for code coverage and the other for reporting purposes (default-prepare-agent and the default-report respectively). In the section of code below, 
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${jacoco.version}</version>
                <executions>
                    <execution>
                       <id>default-prepare-agent</id>
                       <goals>
                           <goal>prepare-agent</goal>
                       </goals>
                    </execution>
                    <execution>
                        <id>default-report</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

 
 
 This plugin over here is used to provide maven surefire reports. Under the configuration section of this plugin, the jacoco-agent-destfile is provided. 
Don’t worry, this file will be automatically created.


            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven.surefire.plugin.version}</version>
                <configuration>
                    <systemPropertyVariables>
                        <jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
        </plugins>
    </build>

The following are the property definitions for the plugins and other dependencies that we have used here.

    <properties>
        <jacoco.version>0.7.5.201505241946</jacoco.version>
        <testng.version>6.9.10</testng.version>
        <maven.surefire.plugin.version>2.18.1</maven.surefire.plugin.version>
    </properties>


This is the most basic setup you would need for the configuration of JaCoCo with your project.

One important modification to the above setup is this. You can fail the build if the code coverage falls below a certain threshold. This will be important if you are thoroughly concerned on the test coverage aspect of the entire project. So this is how you can configure it.

<execution>
    <id>default-check</id>
    <goals>
        <goal>check</goal>
    </goals>
    <configuration>
        <rules>
            <rule implementation="org.jacoco.maven.RuleConfiguration">
                <element>BUNDLE</element>
                <limits>
                    <limit implementation="org.jacoco.report.check.Limit">
                        <counter>INSTRUCTION</counter>
                        <value>COVEREDRATIO</value>
                        <minimum>0.70</minimum>
                    </limit>
                </limits>
            </rule>
        </rules>
    </configuration>
</execution>

Under the two execution sections that we configured before, put this execution as well. It sets a limit of 70% code coverage on the tests. Hence the build will fail if the code / instruction coverage here, falls below 70%.

So thats it for the first way of integrating JaCoCo with your project for code coverage.
Now you can run the build and tests using the command

mvn clean install


2. JaCoCo code coverage with offline instrumentation

First of all lets see what offline instrumentation means.

While the JaCoCo runtime agent instruments classes on the fly. Although this is advantageous, there can be cases where on-the-fly instrumentation is not suitable.

  • Runtime environments that do not support Java agents.
  • Deployments where it is not possible to configure JVM options.
  • Bytecode needs to be converted for another VM like the Android Dalvik VM.
  • Conflicts with other agents that do dynamic classfile transformation.
The above information is taken from the following link. JaCoCo Documentation.

Therefore in such kind of situations, you can use the offline instrumentation method of configuring JaCoCo in your project. So this is how to do it.

The pom file content will look like the following after configuring for offline instrumentation.
The only change that we have done here is removing the execution of the JaCoCo runtime agent and plugging in default-instrument and default-restore-instrumented-classes executions.


<dependencies>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>${testng.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jacoco</groupId>
            <artifactId>org.jacoco.agent</artifactId>
            <classifier>runtime</classifier>
            <version>${jacoco.version}</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${jacoco.version}</version>
                <executions>
                    <execution>
                        <id>default-instrument</id>
                        <goals>
                            <goal>instrument</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>default-restore-instrumented-classes</id>
                        <goals>
                            <goal>restore-instrumented-classes</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>default-report</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>default-check</id>
                        <goals>
                            <goal>check</goal>
                        </goals>
                        <configuration>
                            <rules>
                                <rule implementation="org.jacoco.maven.RuleConfiguration">
                                    <element>BUNDLE</element>
                                    <limits>
                                        <limit implementation="org.jacoco.report.check.Limit">
                                            <counter>INSTRUCTION</counter>
                                            <value>COVEREDRATIO</value>
                                            <minimum>0.70</minimum>
                                        </limit>
                                    </limits>
                                </rule>
                            </rules>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven.surefire.plugin.version}</version>
                <configuration>
                    <systemPropertyVariables>
                        <jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <properties>
        <jacoco.version>0.7.5.201505241946</jacoco.version>
        <testng.version>6.9.10</testng.version>
        <maven.surefire.plugin.version>2.18.1</maven.surefire.plugin.version>
        <maven.failsafe.plugin.version>2.19.1</maven.failsafe.plugin.version>
    </properties>


The explanation can be found in section one above titled “JaCoCo code coverage with JaCoCo runtime agent”.

Now you can run the build and tests using the command

mvn clean install



Comments

  1. Wow.. Very informative article thanks for sharing please keep it up because there is no limit of information so I'm waiting for an awesome article just like that.
    Crackjin
    IDM Crack
    TeamViewer Crack
    PhpStorm Crack
    Tenorshare iCareFone Crack

    ReplyDelete
  2. Thanks for sharing your valuable knowledge with us through this content. Keep on posting such a wonderful blogs.
    Read my blog: Exploratory Data Analysis: Uncovering Patterns in Data

    ReplyDelete

Post a Comment

Popular posts from this blog

How to connect my database instance with elastic beanstalk instance in AWS?

If you have deployed your web application in Elastic Beanstalk in AWS and now you need to connect a database to this instance, and your database is actually residing in a different instance, how can you actually connect them? It's easy with Elastic Beanstalk. I will explain an example scenario that I used for connecting my elastic beanstalk web application with another instance containing my MongoDB database. By looking at this, you can customize as per your need. Don't worry. This is easy. :) The only things you need here are the details about the 1. Database name that you need to connect to. Ex:- "myDB" 2. Port at which the database instance is listening. EX:- In the case of MongoDB, the listening port is 27017 3. Host name of your database instance. EX:- Like localhost, in this case, it will be the Public DNS of your database instance 4. The password of your database if exists. First these details need to be set as environment variables in Elastic Be

How to import the Public Certificate of one WSO2 product to the trust store of another?

To demonstrate this point, I will use the 2 products WSO2 API Manager 2.1.0 (referred as APIM from here onwards) and WSO2 Enterprise Integrator 6.1.1 (referred as EI from here onwards). When using EI as the Business Process Server during configuration of Workflows in APIM, one step to perform is to import the public certificate of EI to the truststore of APIM [1]. So now let's see how this can be done. Step 1: Go to <EI_HOME>/repository/resources/security/ folder and execute the following keytool command. This command is used to export the public certificate of EI as a certificate file called wso2carbon.cer. Since the default keystore in EI is wso2carbon.jks, we have specified it as the keystore and the default alias is wso2carbon. Provide wso2carbon as the keystore password when prompted as it is the default password. After executing the above command from within the security folder in EI, you will see that a file with the name of wso2carbon.cer is created