SQ 9.7
This commit is contained in:
commit
7af501d8ec
97
README.md
Normal file
97
README.md
Normal file
@ -0,0 +1,97 @@
|
||||
# Multi-module Apache Maven example
|
||||
|
||||
This project imports JaCoCo's aggregate XML report to be able to report coverage across modules as well as unit test coverage inside the module.
|
||||
|
||||
For a basic example see [basic maven project](../maven-basic/README.md).
|
||||
|
||||
## Usage
|
||||
|
||||
* Build the project, execute all the tests and analyze the project with SonarQube Scanner for Maven:
|
||||
|
||||
```shell
|
||||
mvn clean verify sonar:sonar
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
This project consists of 3 modules.
|
||||
|
||||
* [`module1`](module1/pom.xml) and [`module2`](module2/pom.xml) contain "business logic" and related unit tests.
|
||||
|
||||
* [`tests`](tests/pom.xml) module contains integration tests which test functionality using both modules.
|
||||
`tests` module is also the one which creates the aggregate coverage report imported into SonarQube.
|
||||
|
||||
To generate the report we configure the JaCoCo plugin to attach its agent to the JVM which is executing the tests in the top level [pom](pom.xml).
|
||||
|
||||
This configuration is done in the `<pluginManagment>` section, so it will be applied on every submodule.
|
||||
|
||||
It is also configured inside the `coverage` profile, so this can be activated as needed (e.g. only in CI pipeline).
|
||||
|
||||
```xml
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
```
|
||||
|
||||
Once we have configured JaCoCo to collect coverage data, we need to generate the XML coverage report to be imported into SonarQube.
|
||||
|
||||
We will use [report-aggregate](https://www.jacoco.org/jacoco/trunk/doc/report-aggregate-mojo.html) goal which collects data from all modules dependent on the `tests` module.
|
||||
|
||||
To achieve this we configure the JaCoCo plugin by configuring execution of `report-aggregate` goal in `verify` phase.
|
||||
|
||||
See [pom.xml](tests/pom.xml)
|
||||
|
||||
```xml
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>report</id>
|
||||
<goals>
|
||||
<goal>report-aggregate</goal>
|
||||
</goals>
|
||||
<phase>verify</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
```
|
||||
|
||||
This will create a report in `tests/target/site/jacoco-aggregate/jacoco.xml`. To import this report we will set
|
||||
`sonar.coverage.jacoco.xmlReportPaths` property with the `${maven.multiModuleProjectDirectory}` so every module knows where the coverage should be imported from
|
||||
|
||||
```xml
|
||||
<properties>
|
||||
<sonar.coverage.jacoco.xmlReportPaths>${maven.multiModuleProjectDirectory}/tests/target/site/jacoco-aggregate/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
|
||||
</properties>
|
||||
```
|
||||
|
||||
Alternately we can set this property on the command line with the `-D` switch:
|
||||
|
||||
```shell
|
||||
mvn -Dsonar.coverage.jacoco.xmlReportPaths=C:\projects\sonar-scanning-examples\sonarscanner-maven-aggregate\tests\target\site\jacoco-aggregate\jacoco.xml clean verify sonar:sonar
|
||||
```
|
||||
|
||||
We have to use an absolute path, because the report will be imported for each module separately and the path is resolved relative to the module dir.
|
||||
|
||||
## Documentation
|
||||
|
||||
[SonarScanner for Maven](https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-maven/)
|
||||
16
module1/pom.xml
Normal file
16
module1/pom.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.sonarqube</groupId>
|
||||
<artifactId>sonarscanner-maven-aggregate</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>module1</artifactId>
|
||||
|
||||
<name>Module 1</name>
|
||||
|
||||
</project>
|
||||
17
module1/src/main/java/com/acme/module1/Module1.java
Normal file
17
module1/src/main/java/com/acme/module1/Module1.java
Normal file
@ -0,0 +1,17 @@
|
||||
package com.acme.module1;
|
||||
|
||||
public class Module1 {
|
||||
|
||||
public void coveredByUnitTest() {
|
||||
System.out.println("This method is covered by unit test");
|
||||
}
|
||||
|
||||
public void coveredByIntegrationTest() {
|
||||
System.out.println("This method is covered by integration test");
|
||||
}
|
||||
|
||||
public void uncovered() {
|
||||
System.out.println("This method is not covered");
|
||||
}
|
||||
|
||||
}
|
||||
12
module1/src/test/java/com/acme/module1/Module1Test.java
Normal file
12
module1/src/test/java/com/acme/module1/Module1Test.java
Normal file
@ -0,0 +1,12 @@
|
||||
package com.acme.module1;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class Module1Test {
|
||||
|
||||
@Test
|
||||
public void coveredByUnitTest() {
|
||||
Module1 module1 = new Module1();
|
||||
module1.coveredByUnitTest();
|
||||
}
|
||||
}
|
||||
16
module2/pom.xml
Normal file
16
module2/pom.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.sonarqube</groupId>
|
||||
<artifactId>sonarscanner-maven-aggregate</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>module2</artifactId>
|
||||
|
||||
<name>Module 2</name>
|
||||
|
||||
</project>
|
||||
16
module2/src/main/java/com/acme/module2/Module2.java
Normal file
16
module2/src/main/java/com/acme/module2/Module2.java
Normal file
@ -0,0 +1,16 @@
|
||||
package com.acme.module2;
|
||||
|
||||
public class Module2 {
|
||||
|
||||
public void coveredByUnitTest() {
|
||||
System.out.println("This method is covered by unit test");
|
||||
}
|
||||
|
||||
public void coveredByIntegrationTest() {
|
||||
System.out.println("This method is covered by integration test");
|
||||
}
|
||||
|
||||
public void uncovered() {
|
||||
System.out.println("This method is not covered");
|
||||
}
|
||||
}
|
||||
11
module2/src/test/java/com/acme/module2/Module2Test.java
Normal file
11
module2/src/test/java/com/acme/module2/Module2Test.java
Normal file
@ -0,0 +1,11 @@
|
||||
package com.acme.module2;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class Module2Test {
|
||||
|
||||
@Test
|
||||
public void coveredByUnitTest() {
|
||||
new Module2().coveredByUnitTest();
|
||||
}
|
||||
}
|
||||
87
pom.xml
Normal file
87
pom.xml
Normal file
@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.sonarqube</groupId>
|
||||
<artifactId>sonarscanner-maven-aggregate</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Example of multi-module Maven project</name>
|
||||
|
||||
<modules>
|
||||
<module>module1</module>
|
||||
<module>module2</module>
|
||||
<module>tests</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<sonar.coverage.jacoco.xmlReportPaths>${maven.multiModuleProjectDirectory}/tests/target/site/jacoco-aggregate/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>29.0-jre</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.sonarsource.scanner.maven</groupId>
|
||||
<artifactId>sonar-maven-plugin</artifactId>
|
||||
<version>3.7.0.1746</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.6</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>coverage</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>prepare-agent</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
47
tests/pom.xml
Normal file
47
tests/pom.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.sonarqube</groupId>
|
||||
<artifactId>sonarscanner-maven-aggregate</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>tests</artifactId>
|
||||
|
||||
<name>Tests</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.sonarqube</groupId>
|
||||
<artifactId>module1</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.sonarqube</groupId>
|
||||
<artifactId>module2</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>report</id>
|
||||
<goals>
|
||||
<goal>report-aggregate</goal>
|
||||
</goals>
|
||||
<phase>verify</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
19
tests/src/test/java/com/acme/its/ModulesTest.java
Normal file
19
tests/src/test/java/com/acme/its/ModulesTest.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.acme.its;
|
||||
|
||||
import com.acme.module1.Module1;
|
||||
import com.acme.module2.Module2;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ModulesTest {
|
||||
|
||||
@Test
|
||||
public void integrationTest1() {
|
||||
new Module1().coveredByIntegrationTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void integrationTest2() {
|
||||
new Module2().coveredByIntegrationTest();
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user