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
gradle中使用cobertura做代码覆盖(转)的更多相关文章
- 完美解决--用VS中的Git做代码管理器,与他人共享代码
1.创建代码仓库,这里说一下为什么要创建仓库,Git不能够作为源代码管理器,vs中自带的也只能够在本地进行管理,要和他们共享的话必须要有服务器端去存储代码,类似于SVN,它就有客户端和服务器端,这里推 ...
- [资源]--完美解决--用VS中的Git做代码管理器,与他人共享代码
1.创建代码仓库,这里说一下为什么要创建仓库,Git不能够作为源代码管理器,vs中自带的也只能够在本地进行管理,要和他们共享的话必须要有服务器端去存储代码,类似于SVN,它就有客户端和服务器端,这里推 ...
- 测者的测试技术手册:自动化单元工具EvoSuie的代码覆盖报告
EvoSuite是由Sheffield等大学联合开发的一种开源工具,用于自动生成测试用例集,生成的测试用例均符合Junit的标准,可直接在Junit中运行.得到了Google和Yourkit的支持. ...
- java代码覆盖实战
Jacoco原理 代码插桩 On-the-fly插桩: JVM中通过-javaagent参数指定特定的jar文件启动Instrumentation的代理程序,代理程序在通过Class Loader装载 ...
- Gradle中的buildScript代码块
在编写Gradle脚本的时候,在build.gradle文件中经常看到这样的代码: build.gradle 1 2 3 4 5 6 7 8 9 buildScript { repositories ...
- [转] Gradle中的buildScript代码块
PS: 在build script中的task apply plugin: 'spring-boot' 需要 classpath("org.springframework.boot:spri ...
- VS中代码覆盖问题
在VS中编写代码时,需要插入代码是,经常是将插入点后面的代码覆盖掉而不是将它向后推. 解决这样的问题,只需要按 Insert 键即可, 我的笔记本是 Fn 加 del
- 测者的测试技术手册:自动的自动化框架EvoSuite集成Cobertura得到可视化的代码覆盖报告
EvoSuite是由Sheffield等大学联合开发的一种开源工具,用于自动生成测试用例集,生成的测试用例均符合Junit的标准,可直接在Junit中运行.得到了Google和Yourkit的支持. ...
- C/C++代码覆盖工具gcov与lcov入门
C/C++代码覆盖工具gcov与lcov入门 gcov是一个可用于C/C++的代码覆盖工具,是gcc的内建工具.下面介绍一下如何利用gcov来收集代码覆盖信息.想要用gcov收集代码覆盖信息,需要在g ...
随机推荐
- http://fonts.googleapis.com/css?打开很慢解决方案
最近, 在写一个demo的时候突然发现加载超级慢, 寻找之下发现了"罪魁祸首", 系引用了http://fonts.googleapis.com/css. 接着在网上看到有网友反映 ...
- 无法解析该名称 outlook必须处于联机,控制面板删除账户
无法解析该名称 outlook必须处于联机,控制面板删除账户
- 努比亚 Z5 mini刷机包 omni4.4.2改动V4.0 自用版 精简 MIUI特效
ROM介绍: 第一版: 1.基于lwang适配的omni4.4.2第二版改动,少量精简改动 2.设置加入"自启项管理",体验更快.更顺滑 3.替换特效为XUI特效 4.改动host ...
- poj1236 有向图加边变成强连通图
给我们一个有向图,有两个问题 1.最少要给多少个点发消息,才能使得所有的点都收到消息(消息可以随边传递) 2.最少需要多少条边才能使得图变成强连通图 对于一个强连通分量,可以当做一个点来考虑,所以我们 ...
- python关于for循环的几个函数
1.enumerate:返回2个值,1是当前的for循环的第几轮,2是循环得到的数值 enumerate works by supplying a corresponding index to eac ...
- C++0x新特性
我是在一个帖子上摘抄的大神语录...感谢supermegaboy大神,给了详尽的解释 下文是一篇转载的Wikipedia的译文,从语言和库双方面概述了C++0x. 右值引用与转移语义 在标准C++语言 ...
- Spring事务讲解示例(转)
Spring 事务Transaction1.事务的属性1.1 事务隔离IsolationLevel1.2 事务传播PropagationBehavior1.3 事务超时Timeout1.4 只读状态R ...
- IT增值服务,客户案例(一)--山东青岛在职人士,2年.Net经验,转Java开发半年
客户总体情况:2年.Net开发经验,2014年刚刚转Java半年.对Java的若干问题不是非常清楚,仅仅是对JSP/Servlet/JavaBean Spring.SpringMVC.Mybatis有 ...
- erlang集群IP及port管理
erlang集群是依靠epmd维护的,epmd是erlang集群节点间port映射的守护进程.负责维护集群内的节点连接.提供节点名称到IP地址及port的解析服务. epmd 自己定义port号 ep ...
- APUE读书笔记-第13章-守护进程
第13章 守护进程 13.1 引言 *守护进程也称精灵进程(daemon)是生存期较长的一种进程.它们常常在系统自举时启动,仅在系统关闭时才终止.因为它们没有控制终端,所以说它们是在后台运行的.UNI ...