How to force Sonar to run Integration tests from Jenkins - maven

I use following things:
maven - to build project
jenkins - for CI
sonar - for code analysis
My project contains unit and integration tests. I have configured above mentioned tools to work together.
Integration tests are separated from unit tests. To run integration test I need to run maven with specific profile.
Sonar executes unit tests and gather metrics.
How can I force Sonar to execute specific profile and gather result from integration tests?
EDIT
My surefire and failsafe sections:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<skipTests>${skip.unit.tests}</skipTests>
<excludes>
<exclude>**/*IT*.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12</version>
<executions>
<execution>
<id>integration-tests</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<skipTests>${skip.integration.tests}</skipTests>
</configuration>
</execution>
</executions>
</plugin>
EDIT 2
When I run jenkins build with clean packag -DskipTests because otherwise my tests will be executed twice.
First time during jenkins build and second time when sonar executes them. The problem is that when I start jenkins build with clean verify goal. I can see that both unit and integration tests are executed. And after this step Sonar starts his job and only unit tests are executed.
EDIT 3
I have managed to work sonar with maven from console. I've added following profile and proper plugin to my pom.xml:
<profile>
<id>sonar</id>
<!-- Enable coverage computation via JaCoCo for Sonar's needs -->
<build>
<plugins>
<!--
Compute integration test coverage for Sonar
Note: REQUIRES MAVEN 3 - throws InstantiationException: java.util.List otherwise
Beware: Sonar doesn't run the verify phase; you should always 'mvn clean install' before running sonar
-->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<propertyName>jacoco.agent.argLine</propertyName> <!-- default: argLine -->
<includes>
<include>pl/cyfronet/**</include>
</includes>
<destFile>${project.build.directory}/jacoco-integration.exec</destFile> <!-- agent -->
<dataFile>${project.build.directory}/jacoco-integration.exec</dataFile> <!-- report -->
</configuration>
<executions>
<execution>
<id>agent</id>
<goals><goal>prepare-agent</goal></goals>
</execution>
<execution>
<!--
Generate coverage report html in target/site/jacoco/ from target/jacoco.exec
Exec.: mvn verify site
-->
<id>report</id>
<phase>site</phase>
<goals><goal>report</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
I've also added settings.xml file to my ~/.m2/ directory.
<settings>
<profiles>
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<!-- Example for MySQL-->
<sonar.jdbc.url>
jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8
</sonar.jdbc.url>
<sonar.jdbc.username>sonar</sonar.jdbc.username>
<sonar.jdbc.password>sonar</sonar.jdbc.password>
</properties>
</profile>
</profiles>
</settings>
After that I run mvn with following parameters:
mvn sonar:sonar -Dsonar.jacoco.itReportPath=target/jacoco-integration.exec. Reports were correctly generated to sonar.
I was trying to use it in my jenkins. I have replaced post-build sonar with maven goal sonar:sonar -Dsonar.jacoco.itReportPath=target/jacoco-integration.exec but it doesn't work. My integration tests are not invoked. Any ideas?

I've managed to do this by calling manual maven scripts from jenkins. So everything is working without Sonar plugin for jenkins. It's not perfect, but it works.

Related

is there any way to skip cucumber scenarios while running unit steps?

mvn install is running cucumber steps also. in our local development, we need to run only unit tests and not the cucumber scenarios. Tried with -Dtest=!com.mycompany.* no luck.
And at the same time, we need to skip our Unit Tests while executing a cucumber scenario, is that possible?
This could be achieved by using build profiles. You should run your unit tests by using the surefire plugin and the cucumber scenarios with the failsafe plugin. Naming conventions for automatic running of tests for surefire and failsafe.
<profiles>
<profile>
<id>jenkins</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<excludes>
<exclude>**/*Test.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M3</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Run this with mvn clean install -Pjenkins. This will only run the integration tests ie scenarios.
To run the unit tests just use mvn clean install. Surefire is invoked ie unit test, by default but not failsafe.

Run exec-maven-plugin on demand only

Is there a way to configure maven (in general) or the exec-maven-plugin so that it is executed on demand only, but linked up to (and including) test?
I have a test main (java) that I use for ad-hoc testing. I can run it fine from within Eclipse. But I also want to run it from the command line.
However, I do not want it to run with the unit tests (test phase).
But it has to be staged after the test phase, because it uses code from the test subtree and it uses the test classpath.
Here is what I have. It works fine, except that it runs as part of the test phase.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<id>adhoc-domain-test</id>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.abc.test.AdHocTest</mainClass>
<classpathScope>test</classpathScope>
</configuration>
</plugin>
If I change the phase to (eg) verify, it still gets executed on mvn install.
To run a plugin on demand only, you can wrap the plugin inside a profile that is not active by default, like this:
<profiles>
<profile>
<id>my-profile</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
...
</plugin>
</plugins>
</build>
</profile>
</profiles>
The profiles element goes directly under the project element. You can now run the plugin like this:
mvn -P my-profile ...

Maven war packaging skipped prior to tests being run

I have a maven project which has some Selenium based integration tests to run in a package called sit. I have configured the failsafe plugin to include test files in the package eg. <include>sit/**/*Test.java</include>.
I am trying to run mvn clean install and when it launches the tests I noticed it hasn't actually run the maven-war-plugin i.e. not packaged it into a war prior to running the tests. If however I run mvn clean install -Dmaven.test.skip=true then it does successfully package the war. (I also have the cargo plugin configured to deploy the war which is how I noticed there was an issue as it fails to deploy a non existing war)
The structure of my pom is similar to the below
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>a</groupId>
<artifactId>a</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<includes>
<include>sit/**/*Test.java</include>
</includes>
</configuration>
<executions>
<execution>
<id>integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Any ideas why it doesn't run the war plugin without setting -Dmaven.test.skip=true?
It does in both scenarios create the class files
Try to rename your test classes for integration tests to be with an *IT.java suffix (or prefix...), since this is the convention for tests to be run by maven-failsafe-plugin.
The *Test.java is another convention for running the tests by maven-surefire-plugin.
So no need to exclude them, just rename it.
Ok it seems the issue was maven-surefire was trying to run the integration tests as unit tests, so we have to explicitly exclude the integration tests from surefires unit tests
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
...
<configuration>
<excludes>
<exclude>sit/**/*Test.java</exclude>
</excludes>
</configuration>
</plugin>

Multi Module Maven Project Code Coverage Issue on Sonar

I have a question related to multi module maven project with JaCoCo and SONAR.
I have a parent and 3 child modules.
parent |-child1 - pom.xml |-child2 - pom.xml |-child3 - pom.xml |-pom.xml
I include the JaCoCo plugin in the parent pom.xml. When I run the mvn clean install sonar:sonar build from parent pom.xml, I see that each child generates its own jacoco.exec file. Something like this child1/target/jacoco.exec, child2/target/jacoco.exec etc . However, there is no jacoco.exec been generated in the parent level.
When I run my sonar analysis, I see that the unit test coverage is showing up as 0.0% on the sonar dashboard.
My question is
1. What should I do to see the unit test coverage for the entire project?
2. To show the one unit test coverage, Does SONAR pick the jacoco.exec file from the parent level or from the child level?
Please help. This is really a road blocker for me. Appreciate all your inputs.
I was facing the same issue, then I included the following in each module pom xml and it worked:
<!-- Sonar START -->
<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.version>0.7.9</jacoco.version>
<!-- Sonar START -->
Plugins :
<!-- SONAR config START -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<append>true</append>
</configuration>
<executions>
<execution>
<id>agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<tasks>
<echo>Project Base Path (WEB):: ${project.basedir}</echo>
<echo>Jacoco exec target path (WEB):: ${sonar.jacoco.reportPath}</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.2</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>2.7</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<argLine>${argLine}</argLine>
</configuration>
</plugin>
<!-- SONAR config END -->
And configure in Jenkins for "Goals and options" as:
sonar:sonar
For Running specific tests :
sonar:sonar -DfailIfNoTests=false -Dtest=<Test Class> test
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..

Sonar does not read Jacoco reports

I have a project whose Integration Tests are run by maven-failsafe-plugin and Unit Tests are run by maven-surefire-plugin.
I use jacoco to generate the coverage reports:
<properties>
<coverage.reports.dir>${project.build.directory}/coverage-reports</coverage.reports.dir>
<sonar.jacoco.reportPath>${coverage.reports.dir}/jacoco-unit.exec</sonar.jacoco.reportPath>
<sonar.jacoco.itReportPath>${coverage.reports.dir}/jacoco-it.exec</sonar.jacoco.itReportPath>
</properties>
[...]
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.5.7.201204190339</version>
<executions>
<execution>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
<configuration>
<propertyName>jacoco.agent.argLine</propertyName>
<destFile>${sonar.jacoco.itReportPath}</destFile>
<dataFile>${sonar.jacoco.itReportPath}</dataFile>
</configuration>
</plugin>
[...]
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.5</version>
<configuration>
<argLine>${jacoco.agent.argLine}</argLine>
</configuration>
</plugin>
[...]
<profile>
<id>dev</id>
<properties>
<sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
</properties>
</profile>
[...]
When I run mvn install the Jacoco coverage reports are sucessfully generated.
But when I run mvn -mvn -Pdev sonar:sonar Sonar uses the Cobertura plugin instead of Jacoco.
I have tried:
1) Set jacoco as the default coverage plugin in Sonar settings [did not work]
2) Provide Jacoco parameters in the command line (e.g., -Dsonar.core.codeCoveragePlugin=jacoco) [did not work as well]
Does anyone have any idea? Thanks.
BTW I'm using Sonar 2.8

Resources