如何计算 Selenium 测试相对于 Web 应用程序代码的代码覆盖率

Posted

技术标签:

【中文标题】如何计算 Selenium 测试相对于 Web 应用程序代码的代码覆盖率【英文标题】:How to calculate code coverage of selenium tests with respect to web application code 【发布时间】:2014-01-21 03:37:56 【问题描述】:

我需要将我的 selenium 测试的代码覆盖率捕获到所覆盖的服务器代码(Web 应用程序源代码)中的源代码量。

例如,登录功能的测试应捕获 Web 应用程序中为登录功能覆盖的代码量。

否则需要知道它在 Web 应用程序代码中触及了哪个包或类以完成一个场景。例如登录

我找不到合适的解决方案,虽然我开始了解 Jacoco 代码覆盖工具并使用 Jacoco Jenkins 插件尝试了一些示例,但没有成功。

我不知道这种可能性。请给我一个关于如何实现这一点的建议,在此先感谢

【问题讨论】:

看看这个javacodegeeks.com/2011/10/… 可能会有一些运气。你如何进行代码覆盖将取决于你如何部署你的应用程序 我在Emma方面取得了一些成功 我很好奇您为什么要查找代码覆盖率统计信息以及您希望从该测量中获得什么。请记住,至少从功能测试的角度来看,即使 100% 的代码覆盖率也不意味着您的应用程序没有缺陷 Steve : 我们有使用 selenium 自动化的手动场景,但我们仍然在这里计算测试项目的开发代码(Web 应用程序代码)的覆盖率,这样我们可以在一定程度上增加测试覆盖率,可能听起来很奇怪,但它是要求的一部分 我倾向于认为覆盖外部系统/集成(用户界面)测试在很大程度上也不是很有用。它与“单元测试”不太一样。 【参考方案1】:

确保你这样做。请注意您使用的是 Gradle、Maven 还是 ANT。但以下概念与任何构建系统都非常相似。

    您必须有一个 .war/.ear 应用程序工件,您需要在 Tomcat / 类似程序后面运行它。 您还需要确保在调试模式下编译了您的主代码,否则 jacoco 会不高兴。 例如:Java 中的 -g 选项和类似的调试选项(如果您使用的是 groovy)。

tasks.withType(Compile) 
    options.debug = true
    options.compilerArgs = ["-g"]

    假设您拥有 .war 并使用 Tomcat。然后在启动Tomcat时。 在 Tomcat 启动脚本中,确保告诉 Tomcat 的 JVM jacocoagent.jar 文件在哪里并传递其他参数。这是我们有时看到的主要缺失点(也就是没有将 jacoco 附加到目标 JVM 的会话并试图获得代码覆盖率)。

例如:我使用传递给 Tomcat 的以下参数启动我的 Tomcat 脚本(-Dxxxx=value 方式)

PROJ_EXTRA_JVM_OPTS=-javaagent:tomcat/jacocoagent.jar=destfile=build/jacoco/ST/jacocoST.exec,append=false

基本上,Tomcat启动脚本会有-Dparameter=value,你可以将上面的参数(Linux/Unix export变量)传递给Tomcat/Target JVM的作用域。

上述参数行在发送到 Tomcat 时,会将 JACOCO 代理 .jar 文件附加到“TARGET”(又名 Tomcat JVM)。在这里,您要告诉 Tomcat 从您的工作区下名为“tomcat”的主管中查找 jacocoagent.jar 文件。它会在 build/jacoco/ST 文件夹下创建一个名为“jacocoST.exec”的 jacoco .exec 文件(也就是 Selenium Test 的 jacoco exec 文件)(我正在使用 Gradle,所以 Gradle 会在您运行构建/编译时创建“构建”文件夹/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 测试运行时的测试页面。

    -- 如果您最终在 Jenkins 中使用“xvfb”插件,您FIRST需要在服务器上启动“Xvfb”服务(Linux/Unix) 运行测试的地方。

    -- 如果您在 Windows 机器上运行非单元测试(也称为集成/Selenium 等),那么您可以在运行测试时看到 GUI 测试弹出。如果您不想看到弹出窗口,那么您的 Jenkins 实例可以将从属(您的 Windows 机器)进程作为服务(“作为服务安装”)运行。如果您将 windows 机器创建为从机,当您在机器上运行 JLNP 安装时,您将看到 Jenkins 已成功启动从机进程的弹出窗口,单击文件 > 作为服务安装将在 windows 机器上运行您的从机作为“无头”。

    当你的测试运行时,你会注意到这一次,jacoco 将根据你为 destfile 参数定义的值创建一个文件夹结构/执行文件,但它仍然是0 或一些小尺寸。

    一旦您的 Selenium/非单元测试完成,您必须“停止”Tomcat/目标 JVM。这会将所有 jacoco 覆盖信息刷新到这个 jacocoST.exec 文件(您希望 jacoco 创建的自定义文件)。 -- 注意:如果你想动态刷新 jacocoST.exec 文件(不需要 Tomcat JVM/会话停止,那么你可以查看 jacoco 文档如何做到这一点,那里有一个主题可以说明这一点,这样您的应用程序可以继续运行,而您不必停止您的应用程序/网络服务)。

    运行 jacocoTestReport 任务,您将看到 jacoco 代码覆盖率。

    确保指定主代码的源/类在哪里。

例如:

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

如果您仍然发现任何问题,请随时联系我。您还可以在 *** 上看到我的一些帖子,了解我是如何实现这一目标的,并将相同的报道发布到 SonarQube。

【讨论】:

我遇到了问题,我做了一切,但系统没有在 build 中创建文件夹 jacoco。 @RoggerFernandes 这意味着任务没有运行(你的测试没有运行,或者 test/someCustomTest 任务没有运行,或者其中任何一个测试任务都没有集成 jacoco在任务级别)。您是否将 jacocoagent.jar 附加到目标 JVM(运行您的 webapp 的 Tomcat)中?如果没有,将跳过 jacoco 步骤(如果您运行 Gradle 任务或 maven 目标。请查看我的其他一些帖子以获取有关此主题的一些提示。【参考方案2】:

毯子可以工作。

这是一个 javascript 库。

您在 HTML 页面中使用 'data-cover' 属性注释导入:

<script src="sourceScript.js" data-cover></script>

...并且毯子将您的 JS 文件替换为带注释的副本,该副本向自身报告统计信息。

重要的步骤是从一揽子获取代码覆盖率统计信息,但如果我没记错的话,Selenium 有一个接口,允许您在浏览器引擎中执行 JavaScript 函数。 API 在这里:

https://github.com/alex-seville/blanket/blob/master/docs/advanced_browser.md

【讨论】:

以上是关于如何计算 Selenium 测试相对于 Web 应用程序代码的代码覆盖率的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Selenium-Grid

Selenium 3 升级到 Selenium 4 应注意哪些

Sahi ---实现 Web 自动化测试

使用 Sahi 实现 Web 自动化测试

使用 Sahi 实现 Web 自动化测试

Selenium