gvdm
gvdm

Reputation: 3166

JaCoCo plugin gives different coverage

I'm using the JaCoCo Maven plugin and agent to measure and retrieve the code coverage data of an application which is tested nightly. This is the schema of the architecture:

Tests architecture

My Maven project is configured with the JMeter Maven plugin to execute some API tests during the Maven verify phase. The Maven command executed by the Jenkins server is the following

mvn verify org.jacoco:jacoco-maven-plugin:0.7.8:dump sonar:sonar -Djacoco.address=TEST_SERVER -Djacoco.destFile=/proj/coverage-reports/jacoco-it.exec -Dsonar.projectKey=sonar_test -Dsonar.projectName=sonar_test -Dsonar.branch=sonar_test -Dsonar.jacoco.itReportPath=/proj/coverage-reports/jacoco-it.exec -Dsonar.java.coveragePlugin=jacoco -Dsonar.language=java

As you can see first the tests are executed through the verify phase, then the jacoco:dump goal retrieves the coverage data from the test server (I configured the server to run the JaCoCo agent) and at last the data is uploaded to my Sonar server.

The "strange" behaviour I'm having is that if I run this command on my computer and then on Jenkins (configuring the Jenkins project accordingly) in the SonarQube page I get different coverage results. Moreover, if I configure the Jenkins project and then I simply COPY it creating a new (but equivalent) Jenkins project, the results are different.

Coverage result for local test

Coverage result with Jenkins

I tried different configurations and cases, but I cannot understand what the problem can be. Am I not considering some JaCoCo constraints (e.g. someting related to the Jenkins project name)?

Upvotes: 2

Views: 2811

Answers (1)

gvdm
gvdm

Reputation: 3166

As said in the question comments, the artifact deployed on the test server and the one compiled during the verify phase on which the report is generated must be exactly the same, so it is not enough that the code is the same.

To solve my problem I had to implement this workflow with Jenkins:

  1. Do a mvn package on the project
  2. Deploy the generated WAR on the remote server using Ansible (we already use Ansible for nightly deploys and other tasks on remote machines)
  3. Run the remote tests without recompiling the wars. To do this I had to add the Maven flag -Dmaven.compiler.useIncrementalCompilation=false (thanks to this and this for the hints) in order to not re-compile the artifacts during the verify phase
  4. Retrieve (dump) the JaCoCo coverage data

So the Maven command described in the question has been split in two commands: the one which creates the package and the one which performs the tests and retrieves the JaCoCo data without recompiling the artifacts.

Upvotes: 1

Related Questions