Gradle jacoco覆盖报告有多个子模块?

时间:2016-07-30 16:01:49

标签: java gradle code-coverage jacoco

是否有人知道如何为java jacoco报告配置gradle文件 包含多个gradle子模块的codecoverage?

我当前的方法只显示当前子模块的代码覆盖,但不显示 兄弟 - 子模式的代码覆盖。

我有这个项目结构

- build.gradle (1)
- corelib/
    - build.gradle (2)
    - src/main/java/package/Core.java
- extlib/
    - build.gradle (3)
    - src/main/java/package/Ext.java
    - src/test/java/package/Integrationtest.java

当我执行gradlew :extlib:check :extlib:jacocoTestReport junit-test" Integrationtest.java" 执行并生成一个codecoverage报告,该报告不包含像Core.java这样的issib类的codecoverage

结果应该包括Ext.java和Core.java的代码库?

我已经阅读了

但没有找到线索

这里是gradle文件的内容

// root build.gradle (1)
// Top-level build file where you can add configuration options 
// common to all sub-projects/modules.
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'
    }
}
allprojects {
    repositories {
        jcenter()
    }
}
// build.gradle (2) subproject build file for corelib.
apply plugin: 'java'
apply plugin: 'jacoco'

dependencies {
}

jacocoTestReport {
    reports {
        xml.enabled true
        html.enabled true
    }
}
// build.gradle (3) subproject build file for extlib.
apply plugin: 'java'
apply plugin: 'jacoco'

dependencies {
    compile project(':corelib')
    testCompile 'junit:junit:4.11'

    // this does not compile
    // jacocoTestReport project(':pixymeta-core-lib')
}

jacocoTestReport {
    reports {
        xml.enabled true
        html.enabled true
    }
}

// workaround because android-studio does not make the test resources available
// see https://code.google.com/p/android/issues/detail?id=64887#c13
task copyTestResources(type: Copy) {
    from sourceSets.test.resources
    into sourceSets.test.output.classesDir
}
processTestResources.dependsOn copyTestResources

[更新2016-08-01]

感谢@Benjamin Muschko我也试过根gradle文件

// https://discuss.gradle.org/t/merge-jacoco-coverage-reports-for-multiproject-setups/12100/6
// https://docs.gradle.org/current/dsl/org.gradle.testing.jacoco.tasks.JacocoMerge.html
task jacocoMerge(type: JacocoMerge) {
   subprojects.each { subproject ->
      executionData subproject.tasks.withType(Test)
   } 

}

但收到错误消息(使用gradle-2.14)

* What went wrong:
Some problems were found with the configuration of task ':jacocoMerge'.
> No value has been specified for property 'jacocoClasspath'.
> No value has been specified for property 'executionData'.
> No value has been specified for property 'destinationFile'.

还有gradle插件https://github.com/paveldudka/JacocoEverywhere,我已经要求提供mulit-submodule支持https://github.com/paveldudka/JacocoEverywhere/issues/16

[更新2016-08-01]我找到了一个基于https://github.com/palantir/gradle-jacoco-coverage

的工作解决方案

请参阅下面我自己的答案

5 个答案:

答案 0 :(得分:6)

最后我找到了这个插件:https://github.com/palantir/gradle-jacoco-coverage为我完成了这项工作:

root gradle.build

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        // see https://jcenter.bintray.com/com/android/tools/build/gradle/
        classpath 'com.android.tools.build:gradle:2.1.0'
        // classpath 'com.android.tools.build:gradle:2.2.0-alpha1'

        // https://github.com/palantir/gradle-jacoco-coverage
        classpath 'com.palantir:jacoco-coverage:0.4.0'      
    }
}

// https://github.com/palantir/gradle-jacoco-coverage
apply plugin: 'com.palantir.jacoco-full-report'

所有

的子项目
apply plugin: 'jacoco'

包含在报告中。

答案 1 :(得分:1)

一种可能的解决方案(具有一些声纳特定部分):

def getJacocoMergeTask(Project proj){
    def jmClosure =  {
        doFirst {
            logger.info "${path} started"
            executionData.each { ed ->
                logger.info "${path} data: ${ed}"
            }
        }
        onlyIf {
            executionData != null && !executionData.isEmpty()
        }
    }

    def jacocoMerge = null
    if(!proj.tasks.findByName('jacocoMerge')){

        jacocoMerge = proj.tasks.create('jacocoMerge', JacocoMerge.class)
        jacocoMerge.configure jmClosure

        // sonar specific part
        proj.rootProject.tasks["sonarqube"].mustRunAfter jacocoMerge

        proj.sonarqube {
            properties {
                property "sonar.jacoco.reportPaths", jacocoMerge.destinationFile.absolutePath
            }
        }
        // end of sonar specific part

        logger.info "${jacocoMerge.path} created"
    } else {
        jacocoMerge = proj.tasks["jacocoMerge"]
    }
    jacocoMerge
}


afterEvaluate { project ->
    def jacocoMerge = getJacocoMergeTask(project)

    project.tasks.withType(Test) { task ->
        logger.info "${jacocoMerge.path} cfg: ${task.path}"

        task.finalizedBy jacocoMerge
        jacocoMerge.dependsOn task

        task.doLast {
            logger.info "${jacocoMerge.path} executionData ${task.path}"
            jacocoMerge.executionData task
        }

        def cfg = configurations.getByName("${task.name}Runtime")
        logger.info "${project.path} process config: ${cfg.name}"

        cfg.getAllDependencies().withType(ProjectDependency.class).each { pd ->
            def depProj = pd.dependencyProject
            logger.info "${task.path} dependsOn ${depProj.path}"
            def jm = getJacocoMergeTask(depProj)

            task.finalizedBy jm
            jm.dependsOn task

            task.doLast {
                logger.info "${jm.path} executionData ${task.path}"
                jm.executionData task
            }
        }
    }
}

这将合并所有项目中的所有executionData,它们在测试期间使用某个项目作为依赖项。

答案 2 :(得分:0)

您需要创建一个类型为JacocoMerge的新任务,该任务聚合来自所有子项目的JaCoCo报告。请参阅此post中的类似讨论。

答案 3 :(得分:0)

您可以创建不包含合并的dtrain = xgb.DMatrix(train_data,label=train_labels) # cross_validate(dtrain) print('training model.....') param = {'num_class':4,'objective':'multi:softmax','eval_metric':['merror'],'max_depth':7,'eta':0.04,'subsample':0.8,'min_child_weight':0.5,'max_delta_step':7,'gamma':2,'lambda':10,'colsample_bytree':0.5} model = xgb.train(param,dtrain,420,[(dtrain,'train')],verbose_eval=20) print('saving model....') model.save_model('xgb_model.bin') print('done!') 文件的合并报告。使用以下内容在exec的根目录下创建一个新任务。

build.gradle

答案 4 :(得分:0)