Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Gradle多模块项目sonarqube 6.2中的覆盖计算错误_Java_Gradle_Sonarqube_Code Coverage_Jacoco - Fatal编程技术网

Java Gradle多模块项目sonarqube 6.2中的覆盖计算错误

Java Gradle多模块项目sonarqube 6.2中的覆盖计算错误,java,gradle,sonarqube,code-coverage,jacoco,Java,Gradle,Sonarqube,Code Coverage,Jacoco,我目前正在使用一个覆盖范围很好的gradle多模块java项目,以及sonarqube 6.2和sonarJava插件4.10.0.1026。我正在使用Gradle 4.0.1、sonarqube插件2.5和jacoco 0.7.9!代码是Java8 由于API驱动的开发,API测试在API项目中作为抽象测试编写,并从为测试提供构造函数的实现项目中调用 分析sonarqube服务器上的项目时,正确测量了实施项目的覆盖率,但IMPL项目测试中包含的API项目的覆盖率为0.0%。这些项目的覆盖率结果

我目前正在使用一个覆盖范围很好的gradle多模块java项目,以及sonarqube 6.2和sonarJava插件4.10.0.1026。我正在使用Gradle 4.0.1、sonarqube插件2.5和jacoco 0.7.9!代码是Java8

由于API驱动的开发,API测试在API项目中作为抽象测试编写,并从为测试提供构造函数的实现项目中调用

分析sonarqube服务器上的项目时,正确测量了实施项目的覆盖率,但IMPL项目测试中包含的API项目的覆盖率为0.0%。这些项目的覆盖率结果将被忽略

当我仅仅使用jacoco插件时,我就能够得到同样的行为。在做了一些研究之后,我找到了一个获得正确的jacoco报告的解决方案:

task codeCoverageReport(type: JacocoReport) {
  description "Creates a unified JaCoCo test report for the project."

  // Gather execution data from all subprojects
  // (change this if you e.g. want to calculate unit test/integration test coverage separately)
  executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec")

  // Add all relevant sourcesets from the subprojects 
  subprojects.each {
    sourceSets it.sourceSets.main
  }

  reports {
    xml.enabled true
    html.enabled true
    html.destination file("${buildDir}/reports/jacoco")
    csv.enabled false
  }
}

// always run the tests before generating the report
codeCoverageReport.dependsOn {
  subprojects*.test
}
我目前的结果如下:

雅科科:

  • JaCoCo(编解码器覆盖报告任务)
    • 73%的教学覆盖率
    • 91%的分行覆盖率
  • 声纳
    • 43.1%的线路覆盖率(计算中仅考虑约30%的线路!)
    • 82.1%的条件覆盖率(仅覆盖约20%的条件!)
  • 因此,声纳中的覆盖结果是不可用的。我读过一篇文章,其中宣布了“sonar.jacoco.reportpath”——从sonar6.2开始的参数,我认为是javaanalyzer4.4之类的。将此参数添加到gradle构建脚本时,脚本不再编译。通过sonar项目管理将jacoco.exec文件添加到sonar时,没有任何更改


    如果有一种方法可以管理sonar来计算正确的覆盖率,那就太好了。

    如果您的测试与您想要覆盖率报告的源位于不同的项目中,那么您需要设置
    附加源dirs
    附加类dirs
    。例如:

    evaluationDependsOn ':foo' 
    task codeCoverageReport(type: JacocoReport) {
        additionalSourceDirs.add project(':foo').sourceSets.main.java.sourceDirectories
        additionalClassDirs.add project(':foo').sourceSets.main.output.classesDirs
        // etc
    } 
    

    Thx@Lance Java!他把我推到一个比下面更干净的解决方案。如果所有子项目都有jacoco报告,那么这种方法也可以。如果像我一样,只有少数项目有一份报告,那么最初的解决方案似乎效果更好

    apply plugin: 'base'
    apply plugin: 'org.sonarqube'
    [...]
    allprojects {
      apply plugin: 'java'
      apply plugin: "jacoco"
      [...]
      test {
        [...]
        jacoco {
          append=true
        }
      }
    }
    [...]
    task jacocoMerge( type: JacocoMerge ) {
      dependsOn( subprojects.jacocoTestReport.dependsOn )
      mustRunAfter( subprojects.jacocoTestReport.mustRunAfter )
      destinationFile = file( "${buildDir}/jacoco/mergedTests.exec" )
      executionData = files( subprojects.jacocoTestReport.executionData )
                           .filter { jacocoReportFile -> jacocoReportFile.exists() }
    }
    tasks.sonarqube.dependsOn jacocoMerge
    [...]
    sonarqube {
      properties {
        [...]
        property "sonar.jacoco.reportPath", "${buildDir}/jacoco/*.exec"
      }
    }
    

    原始答复:

    要把正确的覆盖范围数据传送到声纳需要一些时间。有许多问题需要解决。有时Sonar无法跟踪jacoco在类中的变化,因此测试需要参数:

    append=true
    
    这并没有完成所有的工作。在收集跨项目覆盖率方面仍然存在一个问题。因此,最好的解决方案是强制jacoco将覆盖率数据写入单个.exec文件,并将其交给sonar

    最终解决方案如下所示:

    apply plugin: 'base'
    apply plugin: 'org.sonarqube'
    [...]
    allprojects {
      apply plugin: 'java'
      apply plugin: "jacoco"
      [...]
      test {
        [...]
        jacoco {
          append=true
          destinationFile = file( "${rootProject.buildDir}/jacoco/jacocoTest.exec" ) 
        }
      }
    }
    [...]
    sonarqube {
      properties {
        [...]
        property "sonar.jacoco.reportPath", "${buildDir}/jacoco/*.exec"
      }
    }
    
    现在sonar为我的项目提供了正确的覆盖数据。添加一些附加测试后,结果如下:

    • 总覆盖率91.6%
    • 线路覆盖率91.7%
    • 条件覆盖率91.3%
    • 未覆盖线路36
    • 未覆盖的条件11
    • 第433行
    • 单元测试1114
    • 单元测试错误0
    • 单元测试失败0
    • 已跳过单元测试0
    • 单元测试成功率(%)100.0%
    • 单元测试持续时间4s

    希望这能对你们中的一些人有所帮助……;)

    我不太明白为什么只有一些项目有jacoco,而其他项目没有。您可以使用Gradle的富API(例如和)动态查找它们

    例如:

    [':project1',':project3',':project5'],每种{
    项目(it){
    应用插件:“java”
    应用插件:“jacoco”
    }
    }
    项目(“:合并”){
    集合jacocoProjects=allprojects.findAll{it.plugins.hasPlugin('jacoco'}
    评估依赖于Jacoco项目
    任务jacocoMerge(类型:jacocoMerge){
    dependsOn JacoProject*.tasks.withType(测试)
    executionData JacoCoProject*.tasks.withType(测试)
    }
    任务合并报表(类型:JacocoReport){
    德彭森·贾科科梅
    executionData JacoComge.destinationFile
    添加(文件(jacocoProjects*.sourceset*.java.srcDirs))
    添加(文件(jacocoProjects*.sourceset*.output.classesDir))
    }
    }
    
    Thx。我会检查一下。希望我能让它工作。我会很快回复结果。我能够在你的想法起作用的地方创建一个样本。对我来说,最好的解决方案是下面的答案…@这位先生“下面的答案”没有帮助。你应该A.投票选出正确答案,B.指定写答案的人的用户名,以便稍后有人知道你的意思。有一项任务可以将多个exec文件合并到一个文件中,并在接下来的几天内再次尝试。在第一次测试的最后几天工作不正常。下面是一个示例在gradle测试中,将多个
    测试任务合并到单个项目中,并生成合并报告。您可以调整此多项目设置,感谢现在有时间修改我的项目。覆盖率结果是相同的,但在我看来更干净,管道胶带更少……;)正在更新接受的答案。您应该在调用分析之前将更改推送到存储库。JaCoCo合并解决方案更干净,但不像其他解决方案那样获得跨项目覆盖。已放弃api和测试UTIL项目的覆盖率->91%覆盖率->60%(仅使用唯一具有测试的impl项目)。原因很简单,只有impl项目有.exec文件。。。
    
    [':project1', ':project3', ':project5'].each {
        project(it) {
            apply plugin: 'java'
            apply plugin: 'jacoco'
        }
    }
    
    project(':merger') {
        Collection<Project> jacocoProjects = allprojects.findAll { it.plugins.hasPlugin('jacoco' }
        evaluationDependsOn jacocoProjects 
    
        task jacocoMerge(type: JacocoMerge) {
            dependsOn jacocoProjects*.tasks.withType(Test)
            executionData jacocoProjects*.tasks.withType(Test)
        }
    
        task mergedReport(type: JacocoReport) {
            dependsOn jacocoMerge
            executionData jacocoMerge.destinationFile
            sourceDirectories.add(files(jacocoProjects*.sourceSets*.java.srcDirs))
            classDirectories.add(files(jacocoProjects*.sourceSets*.output.classesDir))
        }
    }