我已经搜查向上和向下的互联网这一个。 有很多半的答案在那里,与Maven的特性,如做${sonar.jacoco.reportPath}
,或org.jacoco:jacoco-maven-plugin:prepare-agent
或设置maven-surefire-plugin
argLine
与-javaagent
。
一些如何,没有回答这些问题,无论是对自己,或者组合,是生产什么我后:覆盖报告,其中显示了一个类所涵盖,如果它在测试更高的堆栈使用,如使用实体通过DAO的,即使它不能完全由它自己的模块中的测试覆盖。
是否有一个明确的配置的地方,要实现这一点,好吗?
Answer 1:
我是在同样的情况你,散布在互联网上一半的答案是很烦人的,因为它似乎是很多人有同样的问题,但没有人可以打扰,充分说明他们是如何解决它。
该声纳的文档是指一个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>
这将使声纳拿起在同一个地方的所有子模块的单元测试报告(在父项目中的目标文件夹)。 它还告诉声纳重用报告手动运行滚动自己的,而不是。 我们只需要通过将该父POM,构建/插件内,使所有子模块jacoco - Maven的插件运行:
<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
会将报告文件中的地方,声纳将寻找并append
使其追加到该文件,而不是覆盖它。 本文将结合所有JaCoCo在同一文件中的所有子模块报告。
声纳将看文件每个子模块,因为这就是我们指出了他在上面,使我们在声纳多模块文件合并单元测试结果。
Answer 2:
常问问题
从自那时以来,我疯了与jacoco我的头顶部的问题。
我的应用程序服务器(JBoss和Glassfish的..)位于伊拉克,叙利亚,无论..是否有可能在其上运行的集成测试时,得到的多模块覆盖? 詹金斯和声纳也都在不同的服务器上。
是。 你必须使用jacoco剂 ,在模式运行output=tcpserver
,jacoco蚂蚁库。 基本上有两个jar
秒。 这会给你99%的成功。
如何jacoco剂的工作原理?
你追加一个字符串
-javaagent:[your_path]/jacocoagent.jar=destfile=/jacoco.exec,output=tcpserver,address=*
在应用服务器JAVA_OPTS并重新启动它。 在此字符串只[your_path]
必须与你的虚拟机,其中应用服务器运行路径jacocoagent.jar,存储(存储它!)来代替。 自那时以来,启动应用程序服务器,所部署的所有应用程序将被动态监测和他们的活动(意为代码的用法)将随时为您在jacocos .exec格式由TCL请求得到。
我可以重置jacoco剂只启动以来,时间在我的测试开始收集执行数据?
是的,为此你需要jacocoant.jar,位于您的工作空间詹金斯Ant构建脚本。
所以基本上我从http://www.eclemma.org/jacoco/需要的是jacocoant.jar位于我詹金斯工作区,jacocoagent.jar位于我的应用程序服务器虚拟机上?
那就对了。
我并不想用蚂蚁,我听说jacoco Maven插件可以做所有的事情太多。
这是不对的,jacoco Maven插件可以采集单元的测试数据和一些集成测试数据(见的Arquillian Jacoco ),但如果你有例如放心测试,在詹金斯一分开构建,并且要显示多模块的覆盖,我可以“看不到插件如何Maven可以帮助你。
究竟jacoco剂生产什么?
只有在覆盖数据.exec
格式。 声纳则可以读取它。
是否jacoco需要知道我所在的java类?
不,不声纳,但并不jacoco。 当你这样做mvn sonar:sonar
路径类的用武之地。
那么,关于ant脚本?
它在你的詹金斯工作空间呈现。 矿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>
两个强制性PARAMS调用此脚本时,你应该通过-Dworkspace=$WORKSPACE
用它来指向您的詹金斯的工作区和-Djacoco.host=yourappserver.com
主机,而无需http://
还要注意,我把我的jacocoant.jar
为$ {}工作区/tools/jacoco/jacocoant.jar
我应该怎么做?
什么时候开始你的应用服务器与jacocoagent.jar?
你把Ant脚本和jacocoant.jar在你的工作空间詹金斯?
如果是最后一个步骤是配置詹金斯建设。 这里是策略:
- 调用Ant目标
jacocoReset
重置所有之前收集的数据。 - 运行测试
- 调用Ant目标
jacocoReport
拿到报告
如果一切是正确的,你会看到it-jacoco.exec
在您的构建工作空间。
看截图,我也有ant
安装在我的工作区$WORKSPACE/tools/ant
目录,但您可以使用一个安装在您的詹金斯。
如何在声纳本报告推?
Maven的sonar:sonar
将做的工作(不要忘记进行配置),将其指向主要的pom.xml那么它会通过所有模块运行。 使用sonar.jacoco.itReportPath=$WORKSPACE/it-jacoco.exec
参数来告诉声纳在您的集成测试报告所在。 每当它会分析新的模块课程,它会寻找有关报道中的信息it-jacoco.exec
。
我已经有jacoco.exec在我的`target`目录,`MVN声纳:sonar`忽略/删除它
默认情况下, mvn sonar:sonar
确实clean
,并删除你的目标目录,使用sonar.dynamicAnalysis=reuseReports
避免。
Answer 3:
NEW WAY自版本0.7.7
由于0.7.7版本有创建一个汇总报告的新方式:
您创建一个单独的“报告”项目,该项目收集(在聚合项目之前,它的模块中执行,因此它不能用于任何目的)的所有必要的报告。
aggregator pom
|- parent pom
|- module a
|- module b
|- report module
根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看起来是这样的:
<!-- 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>
全exmple可以发现在这里 。
Answer 4:
我会后我的解决方案,因为它是从别人略有不同,也花了我一天固体得到正确,与现有的答案的援助。
对于多模块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>
我还发现彼得Kainulainens博客文章“创建代码覆盖率报告的单元和集成测试随着JaCoCo Maven插件”是对事物的JaCoCo设置侧有价值。
Answer 5:
我在父级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>
我把插件管理下的插件定义。
请注意,我定义万无一失属性(surefireArgLine)和故障安全(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>
Answer 6:
有一种方法可以做到这一点。 神奇的是建立一个联合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构建的文件夹。
Answer 7:
<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>
Answer 8:
你可以打电话叫蚂蚁任务合并的行家,把所有的覆盖文件(* .exec)一起在同一个文件。
如果您正在运行单元测试使用阶段作准备包 ,如果您运行集成测试,以便使用后的整合测试 。
这个网站有一个例子,如何调用Maven项目jacoco Ant任务
您可以在声呐使用该合并的文件。
Answer 9:
有单元测试和集成,测试,你可以使用Maven的万无一失,插件和Maven故障保护,插件与限制包含/排除。 我与CDI播放,而在声纳/ jacoco取得联系,所以我在这个项目结束了:
https://github.com/FibreFoX/cdi-sessionscoped-login/
也许它可以帮助你一点点。 在我的pom.xml我用“-javaagent”通过设置指定的测试 - 插件的配置 - 部分argLine选项隐含的。 在Maven项目明确使用ANT事情我不会多到混合两个世界给一个尝试,对我来说它。
我只有一个模块Maven项目,但也许它可以帮助你调整你的工作。
注意:也许不是所有的Maven的插件up2date的,也许有些问题是固定的更高版本
文章来源: How to configure multi-module Maven + Sonar + JaCoCo to give merged coverage report?