gradle中使用cobertura做代码覆盖

gradle很好用,但是默认是没有代码覆盖功能的,只好自己写。曾经在网上找到过别人的一段脚本,虽然也能用,但是有一些不爽的地方,一个原因是它不支持对层级工程中全部代码的覆盖,另一个原因是它用替换build/classes/main里面的class文件,再依赖gradle的单元方式来实现的。我自己写了一个代码覆盖的脚本,可以避免这两个问题,代码如下:

allprojects { 
    apply plugin: 'idea' 
} 

subprojects {
    apply plugin: 'java' 
    apply plugin: 'eclipse' 
    apply plugin: 'maven' 
    apply plugin: 'project-report' 
    sourceCompatibility = 1.6 
    targetCompatibility = 1.6
    [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' 
    dependencies {
        runtime 'org.slf4j:slf4j-log4j12:1.4.2 @jar ' 
        testCompile 'junit:junit:4.8.2' 
        testCompile 'org.easymock:easymock:3.0' 
        testRuntime module('net.sourceforge.cobertura:cobertura:1.9.4') {
            dependencies "asm:asm:3.1", "oro:oro:2.0.8", "asm:asm-tree:3.0"
        } 
        testRuntime 'log4j:log4j:1.2.13' 
        testRuntime('org.apache.ant:ant-junit:1.8.2') {
            transitive = false
        }
    } 
    
    /* START 代码覆盖 */ 
    task runCover(dependsOn: testClasses) << {
        def codeCoverDir = new File(buildDir, "codeCover")
        def codeCoverClassesDir = new File(codeCoverDir, "classes")
        def codeCoverTestReportDir = new File(codeCoverDir, "testReport")
        def codeCoverDataFile = new File(codeCoverDir, "cobertura.ser")
        def originalClassesDir = new File(buildDir, "classes/main")
        def unitTestClassesDir = new File(buildDir, "classes/test")
        def projectPath = project.path 
        ant {
            delete(dir: codeCoverDir, failonerror: false) 
            mkdir(dir: codeCoverDir) 
            mkdir(dir: codeCoverClassesDir) 
            mkdir(dir: codeCoverTestReportDir)
            if (!unitTestClassesDir.exists()) {
                mkdir(dir: unitTestClassesDir)
            }
            taskdef(resource: 'tasks.properties', classpath: configurations.testRuntime.asPath) 
            taskdef(name: 'junit', classname: 'org.apache.tools.ant.taskdefs.optional.junit.JUnitTask', classpath: configurations.testRuntime.asPath) 
            copy(todir: codeCoverClassesDir) {
                fileset(dir: originalClassesDir)
            }
            logger.lifecycle("cobertura-instrument: ${projectPath}") 
            'cobertura-instrument'(datafile: codeCoverDataFile) {
                fileset(dir: codeCoverClassesDir, includes: "**/*.class")
            }
            
            logger.lifecycle("junit: ${projectPath}") 
            junit(haltonfailure: true, showoutput: true, fork: true, forkmode: 'once') {
                sysproperty(key: "net.sourceforge.cobertura.datafile", value: codeCoverDataFile) 
                classpath {
                    pathelement(path: configurations.testRuntime.asPath) 
                    pathelement(location: codeCoverClassesDir) 
                    pathelement(location: unitTestClassesDir)
                } 
                formatter(type: 'plain') 
                batchtest(todir: codeCoverTestReportDir) {
                    fileset(dir: unitTestClassesDir, includes: "**/*Test.class")
                }
            }
        }
    } 
    
    task reportCover(dependsOn: runCover) << {
        def codeCoverDir = new File(buildDir, "codeCover")
        def codeCoverReportDir = new File(codeCoverDir, "coverReport")
        def codeCoverDataFile = new File(codeCoverDir, "cobertura.ser") 
        ant {
            mkdir(dir: codeCoverReportDir) 
            taskdef(resource: 'tasks.properties', classpath: configurations.testRuntime.asPath) 
            'cobertura-report'(destdir: codeCoverReportDir, format: 'html', datafile: codeCoverDataFile, encoding: 'utf8') {
                fileset(dir: "${projectDir}/src/main/java", includes: "**/*.java")
            }
        }
    } 
    /* END */
} 

/** * 在根目录的build/codeCover/coverReport目录里生成整个工程的代码覆盖报告。必须至少有一个子工程存在,才能正常执行 */
task reportCoverAll(dependsOn: subprojects.collect { "${it.path}:runCover" }) << {
    def codeCoverDir = new File(buildDir, "codeCover")
    def codeCoverReportDir = new File(codeCoverDir, "coverReport")
    def codeCoverDataFile = new File(codeCoverDir, "cobertura.ser") 
    ant {
        mkdir(dir: codeCoverReportDir) 
        taskdef(resource: 'tasks.properties', classpath: subprojects.toArray()[0].configurations.testRuntime.asPath) 
        'cobertura-merge'(datafile: codeCoverDataFile) {
            fileset(dir: rootDir, includes: "*/build/codeCover/cobertura.ser")
        }
        'cobertura-report'(destdir: codeCoverReportDir, format: 'html', datafile: codeCoverDataFile, encoding: 'utf8') {
            subprojects.each { 
                fileset(dir: "${it.projectDir}/src/main/java", includes: "**/*.java") 
            }
        }
    }
}

实现的思路就是在每个子工程的build目录下生成codeCover目录,然后把testClasses生成的被测试的代码通过cobertura加工到这个目录下的子目录,再调用junit测试,最后生成报告,与gradle java插件里面的test任务没有任何关系。根工程里面的reportCoverAll可以把各子工程生成的cobertura.ser文件合并,生成统一的报告。

转载于:https://my.oschina.net/komodo/blog/919172

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值