缘起
由于最近在看JUnit实战,看到第5章介绍的了代码覆盖率工具,下载安装并使用时出现了点问题,于是就记录下来了。
Cobertura简介
Cobertura(西班牙语的覆盖)是一个和JUnit集成的代码覆盖率测量工具。Cobertura特性:1.免费,开源2.可以和ant和maven集成,也可以通过命令行调用2.可以生成HTML或者XML格式的报告3.可以按照不同的标准对HTML结果进行排序4.为每个类,包以及整个项目计算所覆盖的代码行与代码分支的百分比例
Cobertura安装和使用
Cobertura的安装没什么可说的,就是从sourcefogre上将软件包下载下来,并放到某个特定的目录中。将该目录放到PATH中方面检索(一般是在.bashrc创建一个PATH=${PATH}:/xxx/cobertura),然后在.bashrc中创建一个COBERTURA_HOME的变量并export出来。具体操作如下;
1.下载Cobertura,官方地址如下:http://sourceforge.net/projects/cobertura/
2.设置环境路径:
PATH=${PATH}:/home/xiajian/software/cobertura-2.0.2/
export COBERTURA=/home/xiajian/software/cobertura-2.0.2/
注意:具体的路径依据个人的喜好而不同
本来以为这下可以执行了,结果执行后抛出异常— xxx ClassNofind,查看了shell文件后发现,开源的哥们更新了工具库没更新脚本中的工具库的脚本文件。没有办法,我只能自己改写一下了(我下载的2.0.2的版本的有这问题,现在的2.0.3也有这个问题)
下面是2.0.2的 cobertura-check.sh文件:
#!/bin/bash
Cobertura=cobertura-2.0.2.jar
ASM=asm-4.1.jar
ASM_TREE=asm-tree-4.1.jar
ASM_COMMONS=asm-commons-4.1.jar
ASM_ANALYSIS=asm-analysis-4.1.jar
ASM_UTIL=asm-util-4.1.jar
LOG=log4j-1.2.9.jar
ORO=oro-2.0.8.jar
Cobertura_Home=$(dirname$0)
#发现一个问题,貌似-cp需要的jar包一定是全限定的名字
ClassPath=${Cobertura_Home}/${Cobertura}:${Cobertura_Home}/lib/${ASM}:${Cobertura_Home}/lib/${ASM_TREE}:${Cobertura_Home}/lib/${ASM_ANALYSIS}:${Cobertura_Home}/lib/${ASM_UTIL}:${Cobertura_Home}/lib/${ASM_COMMONS}:${Cobertura_Home}/lib/${LOG}:${Cobertura_Home}/lib/${ORO}
#其实所有的*.sh文件中唯一的区别是就这里这,java的类的main不同
java-cp ${ClassPath} net.sourceforge.cobertura.check.Main $*
注意: 由于本人使用的Ubuntu,所以就只改写了一下shell脚本,如果是使用的window的话,可以参考
http://blog.csdn.net/xiajian2010/article/details/9790675 进行一下转换. cobertura-2.0.2目录下的那四个脚本文件都要转换(cobertura-instrument.sh ,cobertura-merge.sh,cobertura-check.sh,cobertura-report.sh),仔细查看一下可以发现,除了java主类不一样,其他都是一样的。下面是一些修改的其他一些shell脚本:
cobertura-instrument.sh脚本
#!/bin/bash
Cobertura=cobertura-2.0.2.jar
#asm字节码工具的相关的jar包
ASM=asm-4.1.jar
ASM_TREE=asm-tree-4.1.jar
ASM_COMMONS=asm-commons-4.1.jar
ASM_ANALYSIS=asm-analysis-4.1.jar
ASM_UTIL=asm-util-4.1.jar
LOG=log4j-1.2.9.jar
ORO=oro-2.0.8.jar
Cobertura_Home=$(dirname $0)
#发现一个问题,貌似-cp需要的jar包一定是全限定的名字
ClassPath=${Cobertura_Home}/${Cobertura}:${Cobertura_Home}/lib/${ASM}:${Cobertura_Home}/lib/${ASM_TREE}:${Cobertura_Home}/lib/${ASM_ANALYSIS}:${Cobertura_Home}/lib/${ASM_UTIL}:${Cobertura_Home}/lib/${ASM_COMMONS}:${Cobertura_Home}/lib/${LOG}:${Cobertura_Home}/lib/${ORO}
#其实所有的*.sh文件中唯一的区别是就这里这,java的类的main不同--instrument.Main不同
java -cp ${ClassPath} net.sourceforge.cobertura.instrument.Main $*
cobertura-merge.sh文件:
#!/bin/bash
Cobertura=cobertura-2.0.2.jar
ASM=asm-4.1.jar
ASM_TREE=asm-tree-4.1.jar
ASM_COMMONS=asm-commons-4.1.jar
ASM_ANALYSIS=asm-analysis-4.1.jar
ASM_UTIL=asm-util-4.1.jar
LOG=log4j-1.2.9.jar
ORO=oro-2.0.8.jar
Cobertura_Home=$(dirname $0)
#发现一个问题,貌似-cp需要的jar包一定是全限定的名字
ClassPath=${Cobertura_Home}/${Cobertura}:${Cobertura_Home}/lib/${ASM}:${Cobertura_Home}/lib/${ASM_TREE}:${Cobertura_Home}/lib/${ASM_ANALYSIS}:${Cobertura_Home}/lib/${ASM_UTIL}:${Cobertura_Home}/lib/${ASM_COMMONS}:${Cobertura_Home}/lib/${LOG}:${Cobertura_Home}/lib/${ORO}
#其实所有的*.sh文件中唯一的区别是就这里这,java的类的main不同
java -cp ${ClassPath} net.sourceforge.cobertura.merge.Main $*
cobertura-report.sh文件:
#!/bin/bash
Cobertura=cobertura-2.0.2.jar
ASM=asm-4.1.jar
ASM_TREE=asm-tree-4.1.jar
ASM_COMMONS=asm-commons-4.1.jar
ASM_ANALYSIS=asm-analysis-4.1.jar
ASM_UTIL=asm-util-4.1.jar
LOG=log4j-1.2.9.jar
ORO=oro-2.0.8.jar
Cobertura_Home=$(dirname $0)
#发现一个问题,貌似-cp需要的jar包一定是全限定的名字
ClassPath=${Cobertura_Home}/${Cobertura}:${Cobertura_Home}/lib/${ASM}:${Cobertura_Home}/lib/${ASM_TREE}:${Cobertura_Home}/lib/${ASM_ANALYSIS}:${Cobertura_Home}/lib/${ASM_UTIL}:${Cobertura_Home}/lib/${ASM_COMMONS}:${Cobertura_Home}/lib/${LOG}:${Cobertura_Home}/lib/${ORO}
#其实所有的*.sh文件中唯一的区别是就这里这,java的类的main不同
java -cp ${ClassPath} net.sourceforge.cobertura.reporting.Main $*
使用实例(参考《JUnit实战》第5章的代码)
为了测量测试覆盖率,Cobertura为你指定的类文件创建了instrument后的副本—字节码工具技术(byte-code instrumentation),向现有的编译代码中增加字节码,以便记录什么执行了字节码。
使用以下命令来编译我们的测试用例:
javac-cp junit-4.6.jar -d uninstrumented src/*.java
进行将类instrument化
cobertura-instrument.sh–destination instrumented unistrumented/Calculator.class
cobertura可以和JUnit,Ant集成,也可以和其他的任何测试框架一起工作,与工具无关。为了运行测试,需要在CLASSPATH中加入两个资源:1.Cobertura.jar 2.包含了instrument后的类要在包含了尚未要在uninstrument的类之前。
备注:那么长的命令要一个在命令行里敲,太麻烦了,于是我就写了一个shell脚本-自动化处理。
#!/bin/bash
#编译命令-cp-类路径,-d输出到uninstrumented
javac-cp junit-4.6.jar -d uninstrumented src/*.java
#在class文件中进行代码插桩
cobertura-instrument.sh–destination instrumented uninstrumented/Calculator.class
#执行插桩后的程序,并将相应的执行的信息写入到xxx.ser中
java-cpjunit-4.6.jar:${COBERTURA_HOME}/cobertura-2.0.2.jar:instrumented:unistrumented:-Dnet.sourceforge.cobertura.datafile=cobertura.serorg.junit.runner.JUnitCore TestCalculator
#生成相应的测试报告
cobertura-report.sh--format html --datafile cobertura.ser --destination reports src
小结
难得使用个开源工具这么坑爹的。此外,更加深入一步的了解Cobertura可以参考下面的这些内容:
用 Cobertura 测量测试覆盖率:http://www.ibm.com/developerworks/cn/java/j-cobertura/
使用 Cobertura 和反射机制提高 Java 单元测试中的代码覆盖率:http://www.ibm.com/developerworks/cn/java/j-lo-cobertura/index.html
使用cobertura来测量单元测试的代码覆盖情况:http://huangtut.iteye.com/blog/297464
参考文献
[1]《JUnit 实战》Petar等人著,王魁译 ,Manning图书,人民邮电出版社
[2] 关于Bash---DOS到shell的转换:http://blog.csdn.net/xiajian2010/article/details/9790675