本文共 4427 字,大约阅读时间需要 14 分钟。
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 .
http://sulong.me/2011/08/03/use_cobertura_in_gradle_in_a_better_way转载地址:http://kifco.baihongyu.com/