私はこれをインターネットで上下に検索しました。 ${sonar.jacoco.reportPath}
、またはorg.jacoco:jacoco-maven-plugin:prepare-agent
などのMavenプロパティ、またはmaven-surefire-plugin
で-javaagent
argLine
を設定するなど、多くの半分の答えがあります。
いくつかの方法、これらの答えは、単独で、または組み合わせて、私が望んでいるものを生成していません:独自のモジュールでのテストで完全にカバーされていなかったとしても、DAOによって。
これを達成するために、どこかに決定的な構成がありますか?
多くの人が同じ問題を抱えているように思えたので、私はあなたと同じ状況にありました。
Sonar docs を参照してください 例のある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に、独自に実行する代わりに手動で実行されたレポートを再利用するように指示します。 build/plugins内の親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>
destFile
は、Sonarがそれを探す場所にレポートファイルを配置し、append
は、ファイルを上書きするのではなく、ファイルに追加します。これにより、同じファイル内のすべてのサブモジュールのすべてのJaCoCoレポートが結合されます。
Sonarは、サブモジュールごとにそのファイルを調べます。それが上記で彼が指摘したことなので、Sonarのマルチモジュールファイルのユニットテスト結果を結合したものです。
その時から頭の上からの質問は、ジャココに夢中になりました。
はい。モードoutput=tcpserver
、jacoco ant libで実行される jacoco agent を使用する必要があります。基本的に2つのjar
s。これにより、99%の成功が得られます。
文字列を追加します
-javaagent:[your_path]/jacocoagent.jar=destfile=/jacoco.exec,output=tcpserver,address=*
アプリケーションサーバーJava_OPTSに再起動します。この文字列では、[your_path]
のみを、アプリサーバーが実行されているVMに保存(保存)するjacocoagent.jarへのパスに置き換える必要があります。アプリサーバーを起動すると、デプロイされたすべてのアプリケーションが動的に監視され、そのアクティビティ(コードの使用を意味する)がtcl要求によってjacocos .exec形式で取得できるようになります。
はい、そのためには、jacocoant.jarとjenkinsワークスペースにあるantビルドスクリプトが必要です。
そのとおり。
そうではありません、jacoco mavenプラグインは単体テストデータといくつかの統合テストデータを収集できます( Arquillian Jacoco を参照)が、たとえば、jenkinsの分離ビルドとしてテストを保証し、表示したい場合マルチモジュールカバレッジでは、mavenプラグインがどのように役立つかわかりません。
.exec
形式のカバレッジデータのみ。ソナーはそれを読むことができます。
いいえ、ソナーにはありますが、ジャココにはありません。 mvn sonar:sonar
を実行すると、クラスへのパスが作用します。
Jenkinsワークスペースに表示する必要があります。私のantスクリプト、私はそれを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>
このスクリプトを呼び出すときに渡す必要がある2つの必須パラメーター-Dworkspace=$WORKSPACE
を使用してjenkinsワークスペースと-Djacoco.Host=yourappserver.com
なしのホストをポイントするhttp://
jacocoant.jar
を$ {workspace} /tools/jacoco/jacocoant.jarに置いたことにも注意してください。
Jacocoagent.jarでアプリサーバーを起動しましたか?
JenkinsワークスペースにAntスクリプトとjacocoant.jarを入れましたか?
はいの場合、最後の手順はjenkinsビルドの構成です。戦略は次のとおりです。
jacocoReset
を呼び出して、以前に収集されたすべてのデータをリセットします。jacocoReport
を呼び出してレポートを取得しますすべてが正しければ、ビルドワークスペースにit-jacoco.exec
が表示されます。
スクリーンショットを見ると、$WORKSPACE/tools/ant
dirのワークスペースにant
もインストールされていますが、jenkinsにインストールされているものを使用できます。
Maven sonar:sonar
はジョブを実行し(設定することを忘れないでください)、メインのpom.xmlを指すようにして、すべてのモジュールを実行します。 sonar.jacoco.itReportPath=$WORKSPACE/it-jacoco.exec
パラメーターを使用して、統合テストレポートの場所をソナーに伝えます。新しいモジュールクラスを分析するたびに、it-jacoco.exec
のカバレッジに関する情報を検索します。
デフォルトでは、mvn sonar:sonar
はclean
を実行し、ターゲットディレクトリを削除します。それを避けるには、sonar.dynamicAnalysis=reuseReports
を使用してください。
バージョン0.7.7以降、集計レポートを作成する新しい方法があります。
必要なすべてのレポートを収集する個別の「レポート」プロジェクトを作成します(アグリゲータープロジェクトの任意の目標が実行されるbeforeモジュールであるため、中古)。
aggregator pom
|- parent pom
|- module a
|- module b
|- report module
root pomは次のようになります(モジュールの下に新しいレポートモジュールを追加することを忘れないでください):
<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>
各サブモジュールのPOMを変更する必要はまったくありません。 reportモジュールの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>
完全な例は here にあります。
他のソリューションとは微妙に異なるため、解決策を投稿します。また、既存の回答の助けを借りて、正しく解決するためにしっかりとした日を費やしました。
マルチモジュールMavenプロジェクトの場合:
ROOT
|--WAR
|--LIB-1
|--LIB-2
|--TEST
WAR
プロジェクトがメインWebアプリである場合、LIB
1および2はWAR
が依存する追加モジュールであり、TEST
は統合テストが存在する場所です。 TEST
は(Tomcatプラグインではなく)埋め込みTomcatインスタンスをスピンアップし、WAR
プロジェクトを実行し、一連のJUnitテストを介してテストします。 WAR
およびLIB
プロジェクトには、両方とも独自の単体テストがあります。
このすべての結果として、統合と単体テストのカバレッジが分離され、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
、LIB
、およびTEST
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のセットアップ側にとって有益であることがわかりました。
ユニットテストと統合テストのフェーズが別々にある親レベルの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>
プラグイン定義をプラグイン管理下に置きます。
Surefire(surefireArgLine)およびfailsafe(failsafeArgLine)引数のプロパティを定義して、jacocoが各テストで実行するjavaagentを構成できるようにすることに注意してください。
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ファイルを作成することです。また、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ビルドを開始したフォルダーです。
<sonar.language>Java</sonar.language>
<sonar.Java.coveragePlugin>jacoco</sonar.Java.coveragePlugin>
<sonar.jacoco.reportPath>${user.dir}/target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.jacoco.itReportPath>${user.dir}/target/jacoco-it.exec</sonar.jacoco.itReportPath>
<sonar.exclusions>
file:**/target/generated-sources/**,
file:**/target/generated-test-sources/**,
file:**/target/test-classes/**,
file:**/model/*.Java,
file:**/*Config.Java,
file:**/*App.Java
</sonar.exclusions>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<append>true</append>
<propertyName>surefire.argLine</propertyName>
</configuration>
</execution>
<execution>
<id>default-prepare-agent-integration</id>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
<configuration>
<destFile>${sonar.jacoco.itReportPath}</destFile>
<append>true</append>
<propertyName>failsafe.argLine</propertyName>
</configuration>
</execution>
<execution>
<id>default-report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-report-integration</id>
<goals>
<goal>report-integration</goal>
</goals>
</execution>
</executions>
</plugin>
単体テストと統合テストを行うには、maven-surefire-pluginとmaven-failsafe-pluginを制限付きのinclude/excludesで使用できます。ソナー/ジャココと連絡を取りながらCDIで遊んでいたので、このプロジェクトに行き着きました:
https://github.com/FibreFoX/cdi-sessionscoped-login/
多分それはあなたを少し助けます。私のpom.xmlでは、指定されたtesting-pluginsのconfiguration-sectionでargLine-optionを設定することで暗黙的に「-javaagent」を使用しています。 MAVENプロジェクトでANTを明示的に使用することは、私が試してみるものではありません。
私には単一モジュールのMavenプロジェクトしかありませんが、あなたのプロジェクトを調整するのに役立つかもしれません。
注:多分、すべてのmaven-pluginsが更新されているわけではありません。いくつかの問題は後のバージョンで修正されています