I have been trying to implement JaCoCo offline code coverage in a JBoss server using an instrumented EAR for deployment and the jacococagent.jar in order to track code coverage of external integration testing running against said JBoss.
I have been following guides such as these:
http://www.eclemma.org/jacoco/trunk/doc/offline.html
http://automationrhapsody.com/code-coverage-with-jacoco-offline-instrumentation-with-maven/
I feel I am pretty close as everything SEEMS to be working, however, when I load the coverage report up in eclipse's EclEmma plugin, it reports as 0 coverage for everything (which I know is wrong).
Here's my setup:
Here's the maven plugin configuration:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<configuration>
<!-- <destFile>${sonar.jacoco.reportPath}</destFile> -->
<append>true</append>
<excludes>
<exclude>**/dao/**/*Dao*</exclude>
<exclude>**/dao/**/*DAO*</exclude>
<exclude>**/dao/**/*Vo*</exclude>
<exclude>**/dao/**/*VO*</exclude>
<exclude>**/ui/**/*</exclude>
<exclude>**/*Vo.*</exclude>
<exclude>**/*VO.*</exclude>
<exclude>**/test/**/*</exclude>
<exclude>**/tester/**/*</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
</configuration>
</execution>
<execution>
<id>unit-test-report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${sonar.jacoco.reportPath}</dataFile>
</configuration>
</execution>
<execution>
<id>jacoco-instrument</id>
<phase>test</phase>
<goals>
<goal>instrument</goal>
</goals>
<configuration>
<skip>${jacoco.skip.instrument}</skip>
<!-- <skip>false</skip> -->
</configuration>
</execution>
</executions>
</plugin>
Here's my jacoco-agent.properties file:
destfile=/stage/live_integration_jacoco.exec
output=file
dumponexit=true
append=true
I'm bundling the JaCoCo Agent JARs right inside the EAR as these dependencies (the second one is just what jacocoagent.jar is labelled as in our repository):
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.agent</artifactId>
<version>${jacoco.version}</version>
</dependency>
<dependency>
<groupId>org.jacoco.build</groupId>
<artifactId>org.jacoco.jacocoagent</artifactId>
<version>${jacoco.version}</version>
</dependency>
Here's my process:
I run this on the project: mvn clean install -U -Djacoco.skip.instrument=false
And that generates my instrumented EAR artifact. I have verified that the classes in there are indeed instrumented by JaCoCo by decompiling a few of them.
I take that EAR that has instrumented code, the jacococagent.jar included in it, and the jacoco-agent.popreties file included as well and deploy that to JBoss. JBoss starts just fine (it used to get ClassNotFound exception before I started bundling jacocoagent.jar in it directly).
The "/stage/live_integration_jacoco.exec" file is created at this point with a size of '0'.
I run some tests on and against the server, even some manual testing, then stop the application.
The "/stage/live_integration_jacoco.exec" file now has data (30-60kb of data so far in my observations).
I import that exec file into eclipse and it loads without any errors and shows the classes in the project, however it reports 0 coverage on everything.
Well, I'm not sure what else to try at this point.
Does anyone have some thoughts on how to get it correctly generating the coverage report in my situation?
Thanks!
I suspect that classes deployed on server are compiled with Oracle Java compiler, while classes in Eclipse are compiled with Eclipse Java compiler, and hence JaCoCo can't associate them since they differ. To confirm this - you can try to generate report using the exec file that you try to import, but outside of Eclipse using Ant or Maven. And make sure that you execute generation of report on original (non instrumented) classes, otherwise they also won't match.
Related
I am currently following a tutorial here and saw a POM plugin that I couldn't convert to Gradle, you can find the plugin below. Tried to follow a couple tutorials though they didn't seem to help, the part I am confused about is the executions and what is the general syntax that Gradle expects.
<plugin>
<groupId>com.github.temyers</groupId>
<artifactId>cucumber-jvm-parallel-plugin</artifactId>
<version>5.0.0</version>
<executions>
<execution>
<id>generateRunners</id>
<phase>generate-test-sources</phase>
<goals>
<goal>generateRunners</goal>
</goals>
<configuration>
<!-- Mandatory -->
<!-- List of package names to scan for glue code. -->
<glue>
<package>com.example</package>
<package>com.example.other</package>
</glue>
</configuration>
</execution>
</executions>
</plugin>
As of version 4.x cucumber supports parallel execution. This makes the cucumber-jvm-parallel-plugin for maven obsolete.
You'll will have to create a task that uses gradles JavaExec to call cucumbers CLI directly with --parallel 4.
I don't believe you can use Cucumbers JUnit runner with Gradle to achieve parallel execution because Gradle doesn't install a parallel computer into JUnit but instead forks the the JVM.
Is there a way to include a test folder for Maven to compile from the command line?
I have a set of tests that are in a folder that are not part of the standard set of unit and integration tests. These tests are still useful to run individually until the needed integration tests are built. In Eclipse, I can run these tests individually by right clicking on them and running them as a JUnit test. I am finding that I often want to run more than one test, so I am trying to run them from Maven on the command line. In Maven I can do something like this:
mvn -Dtest=OldTest,OlderTest test
The problem I think I have is that the folder that these tests sit in is not listed as part of the set of test files that need to compile in the POM. I would like to temporarily add the folder, run the tests, and remove the folder without modifying the POM.
I use the Build Helper plugin to add in integration test sources when a certain profile has been activated, for example:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/it/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
Perhaps you can do something similar?
What I am trying to achieve is integrate SonarQube analysis into the build process, so that whenever mvn clean install is run, the code is analyzed with SonarQube. We want to use it for local analysis and also for build on Jenkins. If new issues are found, than the build should fail (we want to use build breaker plugin for that). This way the developer would know that by his code his is going to introduce new issues, and will have to fix them for the build to work.
When I run mvn sonar:sonar, the analysis takes 30 seconds, which is OK.
However, the problem occurs when I am trying to bind sonar goal to maven build phases. I bind sonar to verify phase. The build takes 5 minutes now, which is too long. It should take about 1 minute. The build itself, without SonarQube analysis takes 30 seconds.
Note (may help to figure out what the problem is): the project on which the build is run has multiple modules in it, and I guess that is the problem. It looks like sonar:sonar goal is executed multiple times, once for each submodule, and the whole project is analyzed multiple times (not only the submodules). So, we have 4 submodules, and the report is generated 5 times during the build.
Instead, we want to analyze the whole project only once, not 5 times. It's also important for this 1 analysis to be run at the end of the build, after the cobertura reports are generated for all modules.
So, how do I integrate SonarQube analysis into the build, so that it analyzes my multi-module project only once, in the end, after cobertura reports are generated for all the submodules?
SonarQube plugin properties in parent pom:
<!-- Sonar plugin properties -->
<sonar.jdbc.url>jdbc:url</sonar.jdbc.url>
<sonar.analysis.mode>preview</sonar.analysis.mode>
<sonar.issuesReport.html.enable>true</sonar.issuesReport.html.enable>
<sonar.issuesReport.console.enable>true</sonar.issuesReport.console.enable>
<sonar.host.url>sonar.host:9000</sonar.host.url>
<sonar.language>java</sonar.language>
<sonar.buildbreaker.skip>false</sonar.buildbreaker.skip>
<sonar.qualitygate>Sonar%20way%20with%20Findbugs</sonar.qualitygate>
<sonar.preview.includePlugins>buildbreaker</sonar.preview.includePlugins>
<sonar.exclusions>file:**/target/**</sonar.exclusions>
<branch>development</branch>
Plugins configuration in the project pom:
<!-- Run cobertura analysis during package phase -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>cobertura</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Run sonar analysis (preview mode) during verify phase. Cobertura reports need to be generated already -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>sonar</goal>
</goals>
</execution>
</executions>
</plugin>
IMO, this is just a Maven configuration issue, you're missing the <inherited>false</inherited> element on the execution of sonar:sonar:
<!-- Run sonar analysis (preview mode) during verify phase. Cobertura reports need to be generated already -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>sonar</goal>
</goals>
<inherited>false</inherited>
</execution>
</executions>
</plugin>
I am thinking of using a template engine to generate the web.xml and other things.
Is there as way to to run a java file or a script before the maven install command? Or before the war is generated.
I am not sure what the phase should be, but basically before anyone else looks at the web.xml so I can touch it to make a new valid one.
You can use the exec-maven-plugin to run either a program/script (using the exec goal) or a Java program (using the java goal).
The phase immediately before package is prepare-package (see the Default lifecycle in the Lifecycle Reference), so you could use that. But you might prefer to generate the web.xml earlier in the lifecycle (even as early as generate-resources).
Putting these together, you might try something like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>your_packaging_script</executable>
<!-- optional -->
<workingDirectory>/tmp</workingDirectory>
<arguments>
<argument>--some-option</argument>
</arguments>
</configuration>
</plugin>
Alternatively, you might consider writing your own plugin, especially if you think the idea would be useful for more than one project.
I am new to java world. Our team is using Maven to building everything into single .war file. I am looking for tools to instrument .war files to enable code coverage. Idea is to manually instrument .war file and then run the test.
I looked at couple of tools, but not getting exactly what I am looking for e.g. Emma, jester, cobertura etc. Looking for simple instructions.
If you want to measure code coverage you should use Jacoco. It allows measuring for unit tests and integration tests as well.
All you have to do is to add dependecy:
<dependency>
<groupid>org.jacoco</groupid>
<artifactid>org.jacoco.core</artifactid>
<version>0.6.2.201302030002</version>
<scope>test</scope>
</dependency>
and add jacoco-maven-plugin. Please note that if you won't use Sonar then you have to replace ${sonar.jacoco.reportPath} properties with raw file paths
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.6.2.201302030002</version>
<executions>
<!-- prepare agent for measuring unit tests -->
<execution>
<id>prepare-unit-tests</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
</configuration>
</execution>
<!-- prepare agent for measuring integration tests -->
<execution>
<id>prepare-integration-tests</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<phase>pre-integration-test</phase>
<configuration>
<destFile>${sonar.jacoco.itReportPath}</destFile>
<propertyName>itCoverageAgent</propertyName>
</configuration>
</execution>
</executions>
</plugin>
If you want also to use sonar, then specify such properties:
<properties>
<!-- select JaCoCo as a coverage tool -->
<sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
<!-- force sonar to reuse reports generated during build cycle -->
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<!-- set path for unit tests reports -->
<sonar.jacoco.reportPath>${project.basedir}/target/jacoco-unit.exec</sonar.jacoco.reportPath>
<!-- all modules have to use the same integration tests report file -->
<sonar.jacoco.itReportPath>${project.basedir}/../target/jacoco-it.exec</sonar.jacoco.itReportPath>
</properties>
You can find more details on http://www.kubrynski.com/2013/03/measuring-overall-code-coverage-in.html
Cobertura would support that. See the answer to this question.
Java: measure code coverage for remote scripting tests
If you want to do this in development rather than on your build server, you might want to give eclemma a try. You can launch your webapp in your IDE with eclemma and then simply run whatever test you want to run (outside of eclemma) and it will nicely annotate the code that is running with green.