[maven] 병합 된 커버리지 보고서를 제공하기 위해 다중 모듈 Maven + Sonar + JaCoCo를 구성하는 방법은 무엇입니까?

나는 이것을 위해 인터넷을 위아래로 검색했습니다. 메이븐과 같은 속성과는 거기 절반 답변 많이있다 ${sonar.jacoco.reportPath}, 또는 org.jacoco:jacoco-maven-plugin:prepare-agent또는 설정 maven-surefire-plugin argLine와 함께 -javaagent.

이러한 답변 중 어느 것도 자체적으로 또는 조합하여 내가 추구하는 것을 생성하지 않는 방법 : 사용중인 엔티티와 같이 스택 상위 테스트에서 사용되는 경우 적용되는 클래스를 보여주는 커버리지 보고서 자체 모듈의 테스트로 완전히 다루지 않았지만 DAO에 의해.

이것을 달성하기 위해 어딘가에 확실한 구성이 있습니까?



답변

나는 당신과 같은 상황에 있었고, 인터넷 전체에 흩어져있는 절반의 답변은 많은 사람들이 같은 문제를 가지고있는 것처럼 보였기 때문에 상당히 짜증났습니다. 그러나 아무도 그들이 어떻게 해결했는지 완전히 설명하지 못했습니다.

소나 문서는 참조 예와 GitHub의 프로젝트에 도움이됩니다. 이 문제를 해결하기 위해 한 것은 통합 테스트 논리를 정규 단위 테스트에 적용하는 것이 었습니다 (적절한 단위 테스트는 하위 모듈에 따라 다르지만 항상 그런 것은 아닙니다).

상위 pom.xml에서 다음 속성을 추가합니다.

<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>

이렇게하면 Sonar는 동일한 위치 (상위 프로젝트의 대상 폴더)에있는 모든 하위 모듈에 대한 단위 테스트 보고서를 선택합니다. 또한 Sonar에 자체 롤링 대신 수동으로 실행 된 보고서를 재사용하도록 지시합니다. 빌드 / 플러그인 내부의 부모 pom에이를 배치하여 모든 하위 모듈에 대해 jacoco-maven-plugin을 실행하면됩니다.

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.6.0.201210061924</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>

destFileSonar가 찾는 위치에 보고서 파일을 배치하고 append덮어 쓰지 않고 파일에 추가합니다. 이것은 동일한 파일의 모든 하위 모듈에 대한 모든 JaCoCo 보고서를 결합합니다.

Sonar는 위에서 지적한 것이기 때문에 각 하위 모듈에 대해 해당 파일을 살펴보고 Sonar의 다중 모듈 파일에 대한 결합 된 단위 테스트 결과를 제공합니다.


답변

자주하는 질문

그때부터 머릿속에서 나오는 질문은 자 코코에 미쳐 버렸다.

이라크, 시리아에있는 내 애플리케이션 서버 (jBoss, Glassfish ..)는 무엇이든 .. 통합 테스트를 실행할 때 다중 모듈 커버리지를 얻을 수 있습니까? Jenkins와 Sonar도 다른 서버에 있습니다.

예. 당신은 사용할 필요가 jacoco 에이전트를 해당 모드에서 실행 output=tcpserver, jacoco 개미 LIB. 기본적으로 두 jars. 이것은 당신에게 99 %의 성공을 줄 것입니다.

jacoco 에이전트는 어떻게 작동합니까?

문자열을 추가합니다.

-javaagent:[your_path]/jacocoagent.jar=destfile=/jacoco.exec,output=tcpserver,address=*

애플리케이션 서버 JAVA_OPTS에 연결하고 다시 시작하십시오. 이 문자열 [your_path]에서 앱 서버가 실행되는 VM에 저장된 (저장!) jacocoagent.jar의 경로 로만 교체하면됩니다. 그 이후로 앱 서버를 시작하면 배포 된 모든 애플리케이션이 동적으로 모니터링되고 해당 활동 (코드 사용을 의미)이 tcl 요청에 의해 jacocos .exec 형식으로 가져올 준비가됩니다.

테스트 시작 이후에만 실행 데이터 수집을 시작하도록 jacoco 에이전트를 재설정 할 수 있습니까?

예,이를 위해서는 jenkins 작업 공간에있는 jacocoant.jar 및 ant 빌드 스크립트가 필요합니다.

그래서 기본적으로 http://www.eclemma.org/jacoco/에서 필요한 것은 내 jenkins 작업 공간에있는 jacocoant.jar이고 내 앱 서버 VM에있는 jacocoagent.jar입니까?

맞습니다.

나는 개미를 사용하고 싶지 않다. 나는 jacoco maven 플러그인이 모든 것을 할 수 있다고 들었다.

맞지 않습니다. jacoco maven 플러그인은 단위 테스트 데이터와 일부 통합 테스트 데이터 ( Arquillian Jacoco 참조 )를 수집 할 수 있지만, 예를 들어 젠킨스에서 별도의 빌드로 안심하고 테스트 할 수 있고 다중 모듈 적용 범위를 표시하려면 다음을 수행 할 수 있습니다. maven 플러그인이 어떻게 당신을 도울 수 있는지 보지 못합니다.

jacoco 에이전트는 정확히 무엇을 생산합니까?

.exec형식의 커버리지 데이터 만 . 그러면 Sonar는이를 읽을 수 있습니다.

jacoco는 내 Java 클래스가 어디에 있는지 알아야합니까?

아니, 소나는 있지만 jacoco는 아닙니다. mvn sonar:sonar수업 을 할 때 경로가 작용합니다.

그렇다면 개미 스크립트는 어떻습니까?

그것은 당신의 젠킨스 작업 공간에 제시되어야합니다. 내 개미 스크립트, 나는 jacoco.xml다음과 같이 불렀다 .

<project name="Jacoco library to collect code coverage remotely" xmlns:jacoco="antlib:org.jacoco.ant">
    <property name="jacoco.port" value="6300"/>
    <property name="jacocoReportFile" location="${workspace}/it-jacoco.exec"/>

    <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
        <classpath path="${workspace}/tools/jacoco/jacocoant.jar"/>
    </taskdef>

    <target name="jacocoReport">
            <jacoco:dump address="${jacoco.host}" port="${jacoco.port}" dump="true" reset="true" destfile="${jacocoReportFile}" append="false"/>
    </target>

    <target name="jacocoReset">
            <jacoco:dump address="${jacoco.host}" port="${jacoco.port}" reset="true" destfile="${jacocoReportFile}" append="false"/>
        <delete file="${jacocoReportFile}"/>
    </target>
</project>

이 스크립트를 호출 할 때 전달해야하는 두 개의 필수 매개 변수는이를
-Dworkspace=$WORKSPACE
사용하여 jenkins 작업 공간을 가리키고 -Djacoco.host=yourappserver.com호스트없이http://

또한 jacocoant.jar$ {workspace} /tools/jacoco/jacocoant.jar에 넣었습니다.

다음에 무엇을해야합니까?

jacocoagent.jar로 앱 서버를 시작 했습니까?

젠킨스 작업 공간에 ant 스크립트와 jacocoant.jar를 넣었습니까?

그렇다면 마지막 단계는 젠킨스 빌드를 구성하는 것입니다. 전략은 다음과 같습니다.

  1. ant target jacocoReset을 호출 하여 이전에 수집 된 모든 데이터를 재설정합니다.
  2. 테스트 실행
  3. ant target jacocoReport을 호출 하여 보고서를받습니다.

모든 것이 맞으면 it-jacoco.exec빌드 작업 공간에 표시됩니다.

스크린 샷을보세요. 저는 또한 dir의 ant내 작업 공간에 설치 $WORKSPACE/tools/ant했지만 젠킨스에 설치된 것을 사용할 수 있습니다.

여기에 이미지 설명 입력

이 보고서를 소나로 푸시하는 방법은 무엇입니까?

Maven sonar:sonar이 작업을 수행하고 (구성하는 것을 잊지 마십시오) 모든 모듈을 통해 실행되도록 main pom.xml을 가리 킵니다. sonar.jacoco.itReportPath=$WORKSPACE/it-jacoco.exec매개 변수를 사용 하여 통합 테스트 보고서의 위치를 ​​소나에 알립니다. 새 모듈 클래스를 분석 할 때마다 it-jacoco.exec.

이미`target` 디렉토리에 jacoco.exec가 있습니다.`mvn sonar : sonar`는이를 무시 / 제거합니다.

기본으로 mvn sonar:sonar수행 clean하고 대상 디렉토리를 삭제, 사용 sonar.dynamicAnalysis=reuseReports을 방지하기 위해.


답변

버전 0.7.7 이후의 새로운 방법

버전 0.7.7부터 집계 보고서를 만드는 새로운 방법이 있습니다.

필요한 모든 보고서를 수집하는 별도의 ‘보고서’프로젝트를 만듭니다 (집 계기 프로젝트의 모든 목표는 해당 모듈 보다 먼저 실행 되므로 사용할 수 없습니다).

aggregator pom
  |- parent pom
  |- module a
  |- module b
  |- report module 

루트 치어 같은 외모 (모듈에서 새 보고서 모듈을 추가하는 것을 잊지 마세요)

<build>
<plugins>
  <plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.8</version>
    <executions>
      <execution>
        <id>prepare-agent</id>
        <goals>
          <goal>prepare-agent</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>

각 하위 모듈의 poms는 전혀 변경할 필요가 없습니다. 보고서 모듈 의 pom은 다음과 같습니다.

<!-- Add all sub modules as dependencies here -->
<dependencies>
  <dependency>
    <module a>
  </dependency>
  <dependency>
    <module b>
  </dependency>
 ...

  <build>
    <plugins>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.7.8</version>
        <executions>
          <execution>
            <id>report-aggregate</id>
            <phase>verify</phase>
            <goals>
              <goal>report-aggregate</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

전체 예제는 여기 에서 찾을 수 있습니다 .


답변

다른 사람과 미묘하게 다른 내 솔루션을 게시하고 기존 답변의 도움을 받아 올바른 방법으로 하루를 보냈습니다.

다중 모듈 Maven 프로젝트의 경우 :

ROOT
|--WAR
|--LIB-1
|--LIB-2
|--TEST

를 Where WAR프로젝트의 주요 웹 응용 프로그램입니다, LIB1과 2는 추가 모듈입니다 WAR에 따라 달라집니다 및 TEST통합 테스트가 사는 곳이다.
TEST임베디드 Tomcat 인스턴스 (Tomcat 플러그인을 통하지 않음)를 회전시키고 WAR프로젝트를 실행 하고 JUnit 테스트 세트를 통해 테스트합니다. WARLIB프로젝트는 모두 자신의 단위 테스트가 있습니다.

이 모든 결과는 통합 및 단위 테스트 커버리지가 분리되어 SonarQube에서 구별 될 수 있다는 것입니다.

ROOT pom.xml

<!-- Sonar properties-->
<sonar.jacoco.itReportPath>${project.basedir}/../target/jacoco-it.exec</sonar.jacoco.itReportPath>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.language>java</sonar.language>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>

<!-- build/plugins (not build/pluginManagement/plugins!) -->
<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.6.201602180812</version>
    <executions>
        <execution>
            <id>agent-for-ut</id>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
            <configuration>
                <append>true</append>
                <destFile>${sonar.jacoco.reportPath}</destFile>
            </configuration>
        </execution>
        <execution>
            <id>agent-for-it</id>
            <goals>
                <goal>prepare-agent-integration</goal>
            </goals>
            <configuration>
                <append>true</append>
                <destFile>${sonar.jacoco.itReportPath}</destFile>
            </configuration>
        </execution>
    </executions>
</plugin>

WAR, LIBTEST pom.xml상기 JaCoCo 플러그인 실행을 상속합니다.

TEST pom.xml

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.19.1</version>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
            <configuration>
                <skipTests>${skip.tests}</skipTests>
                <argLine>${argLine} -Duser.timezone=UTC -Xms256m -Xmx256m</argLine>
                <includes>
                    <includes>**/*Test*</includes>
                </includes>
            </configuration>
        </execution>
    </executions>
</plugin>

또한 Petri Kainulainens 블로그 게시물 ‘JaCoCo Maven 플러그인을 사용하여 단위 및 통합 테스트를위한 코드 커버리지 보고서 작성’ 이 JaCoCo 설정 측면에 유용하다는 것을 발견했습니다.


답변

이를 수행하는 방법이 있습니다. 마법은 결합 된 jacoco.exec 파일을 만드는 것입니다. 그리고 maven 3.3.1에서는 이것을 얻는 쉬운 방법이 있습니다. 여기 내 프로필 :

<profile>
    <id>runSonar</id>
    <activation>
        <property>
            <name>runSonar</name>
            <value>true</value>
        </property>
    </activation>
    <properties>
        <sonar.language>java</sonar.language>
        <sonar.host.url>http://sonar.url</sonar.host.url>
        <sonar.login>tokenX</sonar.login>
        <sonar.jacoco.reportMissing.force.zero>true</sonar.jacoco.reportMissing.force.zero>
        <sonar.jacoco.reportPath>${jacoco.destFile}</sonar.jacoco.reportPath>
        <jacoco.destFile>${maven.multiModuleProjectDirectory}/target/jacoco_analysis/jacoco.exec</jacoco.destFile>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>default-prepare-agent</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <configuration>
                            <append>true</append>
                            <destFile>${jacoco.destFile}</destFile>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.sonarsource.scanner.maven</groupId>
                    <artifactId>sonar-maven-plugin</artifactId>
                    <version>3.2</version>
                </plugin>
                <plugin>
                    <groupId>org.jacoco</groupId>
                    <artifactId>jacoco-maven-plugin</artifactId>
                    <version>0.7.8</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</profile>

이 프로필을 부모 pom에 추가하고 전화 mvn clean install sonar:sonar -DrunSonar하면 완전한 보장을 받게됩니다.

여기서 마법은 maven.multiModuleProjectDirectory입니다. 이 폴더는 항상 Maven 빌드를 시작한 폴더입니다.


답변

별도의 단위 및 통합 테스트 단계가있는 부모 수준 pom에서 사용하는 구성입니다.

상위 POM 속성에서 다음 속성을 구성합니다.

    <maven.surefire.report.plugin>2.19.1</maven.surefire.report.plugin>
    <jacoco.plugin.version>0.7.6.201602180812</jacoco.plugin.version>
    <jacoco.check.lineRatio>0.52</jacoco.check.lineRatio>
    <jacoco.check.branchRatio>0.40</jacoco.check.branchRatio>
    <jacoco.check.complexityMax>15</jacoco.check.complexityMax>
    <jacoco.skip>false</jacoco.skip>
    <jacoco.excludePattern/>
    <jacoco.destfile>${project.basedir}/../target/coverage-reports/jacoco.exec</jacoco.destfile>

    <sonar.language>java</sonar.language>
    <sonar.exclusions>**/generated-sources/**/*</sonar.exclusions>
    <sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
    <sonar.coverage.exclusions>${jacoco.excludePattern}</sonar.coverage.exclusions>
    <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
    <sonar.jacoco.reportPath>${project.basedir}/../target/coverage-reports</sonar.jacoco.reportPath>

    <skip.surefire.tests>${skipTests}</skip.surefire.tests>
    <skip.failsafe.tests>${skipTests}</skip.failsafe.tests>

플러그인 관리 아래에 플러그인 정의를 배치합니다.

jacoco가 각 테스트와 함께 실행되도록 javaagent를 구성 할 수 있도록 surefire (surefireArgLine) 및 failsafe (failsafeArgLine) 인수에 대한 속성을 정의합니다.

pluginManagement에서

  <build>
     <pluginManagment>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <fork>true</fork>
                    <meminitial>1024m</meminitial>
                    <maxmem>1024m</maxmem>
                    <compilerArgument>-g</compilerArgument>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
                <configuration>
                    <forkCount>4</forkCount>
                    <reuseForks>false</reuseForks>
                    <argLine>-Xmx2048m ${surefireArgLine}</argLine>
                    <includes>
                        <include>**/*Test.java</include>
                    </includes>
                    <excludes>
                        <exclude>**/*IT.java</exclude>
                    </excludes>
                    <skip>${skip.surefire.tests}</skip>
                </configuration>
            </plugin>
            <plugin>
                <!-- For integration test separation -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.19.1</version>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.maven.surefire</groupId>
                        <artifactId>surefire-junit47</artifactId>
                        <version>2.19.1</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <forkCount>4</forkCount>
                    <reuseForks>false</reuseForks>
                    <argLine>${failsafeArgLine}</argLine>
                    <includes>
                        <include>**/*IT.java</include>
                    </includes>
                    <skip>${skip.failsafe.tests}</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>integration-test</id>
                        <goals>
                            <goal>integration-test</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>verify</id>
                        <goals>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <!-- Code Coverage -->
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${jacoco.plugin.version}</version>
                <configuration>
                    <haltOnFailure>true</haltOnFailure>
                    <excludes>
                        <exclude>**/*.mar</exclude>
                        <exclude>${jacoco.excludePattern}</exclude>
                    </excludes>
                    <rules>
                        <rule>
                            <element>BUNDLE</element>
                            <limits>
                                <limit>
                                    <counter>LINE</counter>
                                    <value>COVEREDRATIO</value>
                                    <minimum>${jacoco.check.lineRatio}</minimum>
                                </limit>
                                <limit>
                                    <counter>BRANCH</counter>
                                    <value>COVEREDRATIO</value>
                                    <minimum>${jacoco.check.branchRatio}</minimum>
                                </limit>
                            </limits>
                        </rule>
                        <rule>
                            <element>METHOD</element>
                            <limits>
                                <limit>
                                    <counter>COMPLEXITY</counter>
                                    <value>TOTALCOUNT</value>
                                    <maximum>${jacoco.check.complexityMax}</maximum>
                                </limit>
                            </limits>
                        </rule>
                    </rules>
                </configuration>
                <executions>
                    <execution>
                        <id>pre-unit-test</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <configuration>
                            <destFile>${jacoco.destfile}</destFile>
                            <append>true</append>
                            <propertyName>surefireArgLine</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>post-unit-test</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                        <configuration>
                            <dataFile>${jacoco.destfile}</dataFile>
                            <outputDirectory>${sonar.jacoco.reportPath}</outputDirectory>
                            <skip>${skip.surefire.tests}</skip>
                        </configuration>
                    </execution>
                    <execution>
                        <id>pre-integration-test</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>prepare-agent-integration</goal>
                        </goals>
                        <configuration>
                            <destFile>${jacoco.destfile}</destFile>
                            <append>true</append>
                            <propertyName>failsafeArgLine</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>post-integration-test</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>report-integration</goal>
                        </goals>
                        <configuration>
                            <dataFile>${jacoco.destfile}</dataFile>
                            <outputDirectory>${sonar.jacoco.reportPath}</outputDirectory>
                            <skip>${skip.failsafe.tests}</skip>
                        </configuration>
                    </execution>
                    <!-- Disabled until such time as code quality stops this tripping
                    <execution>
                        <id>default-check</id>
                        <goals>
                            <goal>check</goal>
                        </goals>
                        <configuration>
                            <dataFile>${jacoco.destfile}</dataFile>
                        </configuration>
                    </execution>
                    -->
                </executions>
            </plugin>
            ...

그리고 빌드 섹션에서

 <build>
     <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
        </plugin>

        <plugin>
            <!-- for unit test execution -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
        </plugin>
        <plugin>
            <!-- For integration test separation -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
        </plugin>
        <plugin>
            <!-- For code coverage -->
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
        </plugin>
        ....

그리고보고 섹션에서

    <reporting>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-report-plugin</artifactId>
            <version>${maven.surefire.report.plugin}</version>
            <configuration>
                <showSuccess>false</showSuccess>
                <alwaysGenerateFailsafeReport>true</alwaysGenerateFailsafeReport>
                <alwaysGenerateSurefireReport>true</alwaysGenerateSurefireReport>
                <aggregate>true</aggregate>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>${jacoco.plugin.version}</version>
            <configuration>
                <excludes>
                    <exclude>**/*.mar</exclude>
                    <exclude>${jacoco.excludePattern}</exclude>
                </excludes>
            </configuration>
        </plugin>
     </plugins>
  </reporting>


답변

JaCoCo의 바이너리 보고서 형식 (* .exec)이 더 이상 사용되지 않고 선호되는 형식이 XML (SonarJava 5.12 이상) 인 새 Sonar 버전에 대한 또 다른 솔루션을 찾았습니다. 솔루션은 매우 간단하며이 주제의 상위 디렉토리에 * .exec 보고서가있는 이전 솔루션과 유사합니다. https://stackoverflow.com/a/15535970/4448263 .

프로젝트 구조가 다음과 같다고 가정합니다.

moduleC - aggregate project's pom
  |- moduleA - some classes without tests
  |- moduleB - some classes depending from moduleA and tests for classes in both modules: moduleA and moduleB

집계 프로젝트의 pom에 다음 Maven 빌드 플러그인 구성이 필요합니다.

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.5</version>
    <executions>
        <execution>
            <id>prepare-and-report</id>
            <goals>
                <goal>prepare-agent</goal>
                <goal>report</goal>
            </goals>
        </execution>
        <execution>
            <id>report-aggregate</id>
            <phase>verify</phase>
            <goals>
                <goal>report-aggregate</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.basedir}/../target/site/jacoco-aggregate</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

그런 다음 maven으로 프로젝트를 빌드하십시오.

mvn clean verify

그리고 Sonar의 경우 관리 GUI에서 속성을 설정해야합니다.

sonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml,../target/site/jacoco-aggregate/jacoco.xml

또는 명령 줄 사용 :

mvn sonar:sonar -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml,../target/site/jacoco-aggregate/jacoco.xml

기술

이렇게하면 기본 디렉토리에있는 각 모듈에 대한 바이너리 보고서가 생성 target/jacoco.exec됩니다. 그런 다음 기본 디렉토리에있는 각 모듈에 대한 XML 보고서를 만듭니다 target/site/jacoco/jacoco.xml.. 그런 다음 각 모듈의 ${project.basedir}/../target/site/jacoco-aggregate/상위 디렉터리에 상대적인 사용자 지정 디렉터리의 각 모듈에 대한 집계 보고서를 만듭니다 . moduleA 및 moduleB의 경우 이것은 공통 경로 moduleC/target/site/jacoco-aggregate/입니다.

moduleB는 moduleA에 종속되므로 moduleB는 마지막에 빌드되고 해당 보고서는 Sonar에서 모듈 A와 B 모두에 대해 집계 커버리지 보고서로 사용됩니다.

집계 보고서 외에도 JaCoCo 집계 보고서에는 종속성에 대한 커버리지 데이터 만 포함되므로 일반 모듈 보고서가 필요합니다.

이 두 가지 유형의 보고서는 Sonar에 대한 전체 범위 데이터를 제공합니다.

약간의 제한이 있습니다. 프로젝트의 상위 디렉토리에 보고서를 작성할 수 있어야합니다 (권한이 있어야 함). 또는 jacoco.skip=true루트 프로젝트의 pom.xml (moduleC)과 jacoco.skip=false클래스 및 테스트가있는 모듈 (moduleA 및 moduleB) 에서 속성 을 설정할 수 있습니다 .