zoukankan      html  css  js  c++  java
  • gradle中使用cobertura做代码覆盖(转)

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    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文件合并,生成统一的报告。

    This work, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.


    http://sulong.me/2011/08/03/use_cobertura_in_gradle_in_a_better_way

  • 相关阅读:
    LUA学习
    python中的面向对象学习以及类的多态
    python中的面向对象学习之继承实例讲解
    python中的面向对象学习以及类的继承和继承顺序
    python中的面向对象学习以及类的封装(这篇文章初学者一定要好好看)
    python中的re模块
    python中configparser模块的使用
    python中装饰器
    python中简单的递归(断点报错的小福利)
    python中函数与函数式编程(二)
  • 原文地址:https://www.cnblogs.com/softidea/p/5133641.html
Copyright © 2011-2022 走看看