maven JaCoCo for site phase only - maven

We have JaCoCo working in our POM and it runs and reports every time we run clean install.
What we would really like to do is only run JaCoCo when a maven site is run.
I have tried adding:
...
<configuration>
<skip>${jacoco.skip}</skip>
....
And setting jacoco.skip to true for the build phase, but in the reporting section, I have added:
...
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
<configuration>
<skip>false</skip>
<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
...
But this does not work. Setting jacoco.skip to true does prevent JaCoCo running on normal maven clean install's but also appears to affect the reporting.
Question: How would I configure maven so that JaCoCo runs successfully for a maven site, but does not run for a mvn clean install?

The simplest way is to delegate it to a Maven profile, removing its configuration for your build section and placing it into a profile as following:
<profiles>
<profile>
<id>jacoco</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.1.201405082137</version>
<configuration><!-- here --></configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.1.201405082137</version>
</plugin>
</plugins>
</reporting>
</profile>
</profiles>
You can then add your custom configuration there.
Then normal builds will not apply it, while you could always activate it via:
mvn clean install -Pjacoco
or
mvn site -Pjacoco

Related

Jenkins SonarQube plugin Multi Module Code Coverage Not Displaying

so we have a Spring Boot maven based project, which we split into multi modules which all works perfectly fine in unit tests and Jenkins, but coverage is not showing up in Sonar at all.
This is the structure of our application:
ApplicationRoot
-SharedCommonModule
--main
---java
-----com...(SomeModule.java)
--test
----com....(SomeModuleTest.java)
-ApplicationModule
--main
---java
-----com...(Application.java)
--test
----com....(ApplicationTest.java)
Parent pom file config:
<properties>
<!-- Sonar -->
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.language>java</sonar.language>
<jacoco.destFile>${sonar.jacoco.reportPath}</jacoco.destFile>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<append>true</append>
</configuration>
<executions>
<execution>
<id>agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
SharedCommonModule pom:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
Main ApplicationModule pom file:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.org.Application</mainClass>
</configuration>
</plugin>
</plugins>
</build>
Jenkins SonarQube plugin configuration:
sonar.projectKey=com.Application
sonar.projectName=ApplicationModule
sonar.projectVersion=1.0.0.${BUILD_NUMBER}
sonar.sources=src/main
sonar.tests=src/test
sonar.java.binaries=target/classes
sonar.jacoco.reportPaths=target/jacoco.exec
sonar.modules=ApplicationModule,SharedCommonModule
ApplicationModule.sonar.projectName=ApplicationModule
SharedCommonModule.sonar.projectName=SharedCommonModule
We have researched and tried to hack it together from multiple examples, but nothing seems to work - closest we've got, is for Sonar to show some coverage, while some classes would show 0% coverage even though we know for sure we have UTs that used those classes (tested via IntelliJ).
So, without without the added properties and build xml sections above, we get partial coverage, only for ApplicaitonModule, I think all reported uncovered classes, belong to SharedCommonModule
EDIT: I want to clarify, the combined jacoco.exec file does show coverage for classes when loaded in IntelliJ Coverage tool, but Sonar does not show coverage for the very same classes in its report (which is generated only when I remove the build and properties xml elements in the parent pom).
Please help :)
You have Maven projects, so you should start using Sonar Scanner for Maven.
It is smart enough to generate all parameters for you.
If you remove:
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<jacoco.destFile>${sonar.jacoco.reportPath}</jacoco.destFile>
<destFile>${sonar.jacoco.reportPath}</destFile>
Jenkins SonarQube plugin configuration
add to parent pom file:
<name>ApplicationModule</name>
<properties>
<sonar.sources>src/main</sonar.sources>
<sonar.tests>src/test</sonar.tests>
<sonar.projectKey>com.Application</sonar.projectKey>
</properties>
add to SharedCommonModule pom file:
<name>SharedCommonModule</name>
add to ApplicationModule.pom file:
<name>ApplicationModule</name>
and finally execute:
mvn sonar:sonar -Dsonar.projectVersion="1.0.0.${BUILD_NUMBER}"
After that you should see missing coverage data.
Btw. it is not recomended to set sonar.projectKey for Maven projects. I set it to the same value, so your project will be accessible under the same link.

Code Coverage not populated after sonar analysis

I am using sonarqube5.6.1.
I have a multi module project for which i am running sonar analysis using the below command.
mvn org.sonarsource.scanner.maven:sonar-maven-plugin:3.1.1:sonar -Dsonar.host.url=http://bamboo.in.XXX.com:8085 -Dsonar.analysis.mode=publish -Dsonar.issuesReport.html.enable=true -Dsonar.dynamicAnalysis=false
But code coverage is not getting populated at all.
Can some one help. I could see the below warnings, Not sure if that's the reason.
[INFO] Process project properties
[WARNING] /!\ A multi-module project can't have source folders, so '/ssdd5/sameenud/dev/trunk/AAAA/BBBB/CCCC/DDDD/src/main/java' won't be used for the analysis. If you want to analyse files of this folder, you should create another sub-module and move them inside it.
The folder structure we have is as below,
AAAA
--BBBB
pom.xml
---CCCC
pom.xml
---DDDD
pom.xml
I tried compiling it manual, But no luck, Same problem.
I had the similar issue, 0.0% coverage & no unit tests count on Sonar dashboard with SonarQube 6.7.2:
Maven : 3.5.2,
Java : 1.8,
Jacoco : Worked with 7.0/7.9/8.0,
OS : Windows
After a lot of struggle finding for correct solution, resolved issue with this configuration my parent pom looks like:
<properties>
<!--Sonar -->
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.language>java</sonar.language>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.4.0.905</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<append>true</append>
</configuration>
<executions>
<execution>
<id>agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
I've tried few other options like jacoco-aggregate & even creating a sub-module by including that in parent pom but nothing really worked & this is simple. I see in logs <sonar.jacoco.reportPath> is deprecated,but still works as is and seems like auto replaced on execution or can be manually updated to <sonar.jacoco.reportPaths> or latest. Once after doing setup, in cmd start with mvn clean install then mvn org.jacoco:jacoco-maven-plugin:prepare-agent install & then do mvn sonar:sonar , this is what I've tried please let me know if some other best possible solution available.Hope this helps!! If not please post your question..
SonarQube (and more specifically SonarJava analyzer) is not computing the coverage. You have to provide a coverage report in order for the analysis to import its results in the SonarQube UI and display coverage.
See the documentation for more information on how to achieve this.

How can I run Cucumber test using explicit Maven goal?

I have an application contains both Cucumber and JBehave test, I want to be able to run one of them optionally every time, I can do that with JBehave by explicit Maven goal, but the problem is that Cucumber run implicitly with each build or test, is there anyway to stop and run it o choice?
You can achieve this by configuring the Maven Surefire Plugin as part of your default build or/and via a profile.
If your Maven build section, you can skip the Cucumber tests by default (given that they either have all the same suffix or belong all to the same package, alternatively you can arrange them to meet any of these two criterias):
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<excludes>
<!-- classes that include the name CucumberTest, as an example -->
<exclude>**/*CucumberTest*.java</exclude>
<!-- classes in a package whose last segment is named cucumber, as an example -->
<exclude>**/cucumber/*.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>
As such, Maven by default (as part of the default build) will skip your Cucumber tests.
Then, you can configure a Maven Profile to run exclusively the Cucumber tests with a counterpart of the Maven Surefire Plugin configuration as following:
<project>
[...]
<profiles>
<profile>
<id>cucumber-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<!-- Include your Cucumber tests, as an example -->
<include>**/*CucumberTest.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
<profile>
</profiles>
[...]
</project>
Then running mvn clean install -Pcucumber-tests will run your Cucumber tests.
This approach would give you more flexibility on configuration in both scenarios (default or cucumber tests build) and you could swap the behavior according to your needs.
Alternatively, for a simpler (but less flexible) approach, you could follow the suggestion on another SO answer and use a Maven property to have a switch cucumber tests on/off as following:
<properties>
<exclude.cucumber.tests>nothing-to-exclude</exclude.cucumber.tests>
</properties>
<profiles>
<profile>
<id>exclude-cucumber</id>
<properties>
<exclude.cucumber.tests>**/*Cucumber*.java</exclude.cucumber.tests>
</properties>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>${exclude.cucumber.tests}</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
Using the configuration above, by default Maven will execute Cucumber tests and skip them when executing mvn clean install -Pexclude-cucumber (the profile will change the content of the exclude.cucumber.tests property and as such change the Surefire plugin filter). You can of course swap the behavior is as well and have an include-cucumber profile instead.

maven release:prepare junit

I have a need to only run a specific jUnit when the mvn release:prepare is executed. I don't want this to run under mvn install or any other goal as this jUnit is designed to see if the developer has executed a database activity first.
Is there any way to either have the junit know, by parameter(?), that the process under execution is release:prepare?
Or, is there a way to define within the pom.xml that this jUnit only runs on that goal?
I've been doing some searching on this and I cannot seem to find a solution as I'm not that good at maven as of yet. Any help is appreciated!
I haven't done exactly what you want but the key is to use the <executions> section under the SureFire :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
... exclude the test from normal execution ...
</configuration>
<executions>
<execution>
<id>release-phase</id>
<phase>release-prepare</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
... fill this in to include the tests you want ...
</configuration>
</execution>
</executions>
<plugin>
You will also want to exclude that test in the normal <configuration> section.
There is some related information HERE
Others are close... but no cigar.
When Maven runs a release, there are no special phases for the release process. What you want to do is add a profile that is configured to include the test you want, e.g.
<profiles>
<profile>
<id>release-preflight-checks</id>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>release-preflight-checks</id>
<goals>
<goal>test</goal>
</goals>
<configuration>
.. include your test here
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Then you need to configure surefire by default to not execute your preflight check
<build>
<plugins>
...
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
.. exclude your test here
</configuration>
</plugin>
...
</plugins>
</build>
And then finally, you need to tell Maven that this profile should be active only during release:prepare's forked execution
<build>
<plugins>
...
<plugin>
<artifactId>maven-release-plugin</artifactId>
<configuration>
...
<preparationGoals>clean verify -P+release-preflight-checks</preparationGoals>
...
</configuration>
</plugin>
...
</plugins>
</build>
Note: it is vitally important to have the + in front of the profile name so that you are adding the profile to the list of active profiles otherwise your release:prepare step will not be validating that the build works with the release profile active and you can have a subsequent release:perform fail.
Note: A less complex route would be to just put the surefire configuration into the release profile that you are using (by default that has the id of release but that is more error prone as you could change that via the parent pom - e.g. if you decide to push your project to central, the sonatype-oss-parent changes the release profile to sonatype-release - and then you won't see the build being failed as the test would not be executed until you change your pom to match new the release profile's id... using the -P+release-preflight-checks ensures that the profile is always active for release:prepare and additionally has the benefit of meeting the requesters original requirement completely - i.e. only runs for release:prepare and doesn't run for release:perform which would be the case if the execution was added to the release profile)

Run Junit Suite using Maven Command

I have multiple Junit test suites (SlowTestSuite, FastTestSuite etc). I would like to run only specific suite using maven command. e.g.
mvn clean install test -Dtest=FastTestSuite -DfailIfNoTests=false
but its not working. Just not running any test at all. Any suggestions please.
I have achieved this by adding property into pom as:
<properties>
<runSuite>**/FastTestSuite.class</runSuite>
</properties>
and maven-surefire-plugin should be:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>${runSuite}</include>
</includes>
</configuration>
</plugin>
so it means by default it will run FastTestSuite but you can run other test e.g. SlowTestSuite using maven command as:
mvn install -DrunSuite=**/SlowTestSuite.class -DfailIfNoTests=false
The keyword you missed is maven-surefire-plugin :http://maven.apache.org/plugins/maven-surefire-plugin/.
Usage is :
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.1</version>
<configuration>
<includes>
<include>**/com.your.packaged.Sample.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>
If you make a little search on stack overflow, you may find information :
Running a JUnit4 Test Suite in Maven using maven-failsafe-plugin
Using JUnit Categories with Maven Failsafe plugin
In addition, you may define profile, like fastTest, that will be triggered by adding parameter to cmd line :
mvn package -PfastTests
This profile would include some inclusions too.

Resources