确保你这样做。请注意确定您使用的是 Gradle、Maven 还是 ANT。但以下概念与任何构建系统都非常相似。
- You must be having a .war/.ear app artifact that you need to run behind Tomcat / similar.
- 您还需要确保在调试模式下编译主代码,否则 jacoco 会不高兴。
- 例如:Java 中的 -g 选项和类似的调试选项(如果您使用的是 groovy)。
tasks.withType(Compile) {
options.debug = true
options.compilerArgs = ["-g"]
}
- Lets say you have the .war and using Tomcat. Then while starting Tomcat.
- 在 Tomcat 启动脚本中,确保您告诉 Tomcat 的 JVM jacocoagent.jar 文件在哪里并传递其他参数。这是我们有时会看到的主要缺失点(也称为不将 jacoco 附加到目标 JVM 的会话并尝试获取代码覆盖率)。
例如:我启动 Tomcat 脚本,并将以下参数传递给 Tomcat(-Dxxxx=值方式)
PROJ_EXTRA_JVM_OPTS=-javaagent:tomcat/jacocoagent.jar=destfile=build/jacoco/ST/jacocoST.exec,append=false
基本上,Tomcat启动脚本都会有-Dparameter=value,你可以传递上面的参数(Linux/Unixexport变量)到 Tomcat/目标 JVM 的范围。
上面的参数行发送到 Tomcat 时,会将 JACOCO 代理 .jar 文件附加到“TARGET”(又名 Tomcat JVM)。在这里,您告诉 Tomcat 在您的工作空间下从名为“tomcat”的目录中查找 jacocoagent.jar 文件。它将在 build/jacoco/ST 文件夹下创建一个名为“jacocoST.exec”的 jacoco .exec 文件(又名 Selenium Test 的 jacoco exec 文件)(我正在使用 Gradle,因此 Gradle 会在您运行构建/编译时创建“build”文件夹) /test/integrationTest/customSeleniumTaskThatYouMightHaveCreated)。
注意:这意味着您不必在测试任务中指定 jacoco 部分(因为它将在您的 BUILD 系统的 JVM 中运行 Gradle、Maven 或 ANT,无论您拥有什么)。
//We don't need jacoco for non-unit tests type of tasks as Jacoco won't be able to find any coverage if done this way. Jacoco agent file needs to be attached/visible to the TARGET's JVM (where you run your application via a .war / .ear etc).
jacoco {
// ... As Gradle runs Unit tests (while doing build), they run free, in the same JVM where Gradle runs the build so Unit test have visibility to the main classes in the same JVM (which Gradle is using to run the build). Thus, you can use jacoco section in Gradle for running unit tests. BUT,
// ... Don't use this section for running Integration, Acceptance, Selenium tests which run on a target JVM. Instead attach jacocoagent.jar and specify jacoco parameters to the target JVM.
}
-
一旦 Tomcat 启动并运行,就可以运行 Selenium 测试了。
笔记:
-- 我在 Linux/Unix 机器上使用 Jenkins,“xvfb”插件非常方便,即现在我可以在 HEADLESS 模式下运行 Selenium GUI 测试,并且我不会通过弹出窗口来打扰运行测试的机器上的任何用户GUI 测试运行时的测试页面。
-- 如果你最终使用“xvfb“ Jenkins 中的插件,你FIRST需要开始”Xvfb“运行测试的服务器(Linux/Unix)上的服务。
-- 如果您在 Windows 计算机上运行非单元测试(又名集成/Selenium 等),那么您可以在运行测试时看到弹出的 GUI 测试。如果您不想看到弹出窗口,那么您的 Jenkins 实例可以将从属(您的 Windows 计算机)进程作为服务运行(“安装为服务”)。如果您将 Windows 计算机创建为从属计算机,则当您在计算机上运行 JLNP 安装时,您将看到一个弹出窗口,表明 Jenkins 已成功启动从属进程,单击“文件”>“安装为服务”将在 Windows 计算机上运行您的从属计算机作为“无头”。
当您的测试运行时,您会注意到这一次,jacoco 将根据您定义的值创建一个文件夹结构/exec 文件destfile参数,但它仍然是 0 或一些小尺寸。
一旦您的 Selenium/非单元测试完成,您必须“停止”Tomcat/目标 JVM。这会将所有 jacoco 覆盖信息刷新到此 jacocoST.exec 文件(您希望 jacoco 创建的自定义文件)。
-- 注意:如果您希望即时刷新 jacocoST.exec 文件(不需要 Tomcat JVM/会话停止,那么您可以查看 jacoco 文档如何做到这一点,那里有一个主题讲述了这一点,这样您的应用程序就可以继续运行,而不必停止您的应用程序/网络服务)。
-
运行 jacocoTestReport 任务,您将看到 jacoco 代码覆盖率。
for ex:
jacocoTestReport {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
ignoreFailures = true
//UT=is for Unit tests, IT=integrationTest, AT=acceptanceTest, ST=Selenium GUI tests.
//executionData = files('build/jacoco/UT/jacocoUT.exec')
//executionData = files('build/jacoco/IT/jacocoIT.exec')
//executionData = files('build/jacoco/UT/jacocoUT.exec', 'build/jacoco/IT/jacocoIT.exec')
//executionData = files(['build/jacoco/UT/jacocoUT.exec', 'build/jacoco/IT/jacocoIT.exec'])
//OR use the following way for all.
executionData = fileTree(dir: 'build/jacoco', include: '**/*.exec')
reports {
xml{
enabled true
//Following value is a file
destination "${buildDir}/reports/jacoco/xml/jacoco.xml"
}
csv.enabled false
html{
enabled true
//Following value is a folder
destination "${buildDir}/reports/jacoco/html"
}
}
//sourceDirectories = files(sourceSets.main.allJava.srcDirs)
sourceDirectories = files('src/java')
//sourceDirectories = files(['src/java','src/groovy'])
classDirectories = files('build/classes/main')
//------------------------------------------
//additionalSourceDirs = files(['test/java','test/groovy','src/java-test', 'src/groovy-test'])
//additionalSourceDirs += files('src/java-test')
}
如果您仍然发现任何问题,请随时联系我。您还可以在 stackoverflow 上看到我的一些帖子,了解我如何实现这一目标,并向 SonarQube 发布相同的报道。