由于最近在看JUnit实战,看到第5章介绍的了代码覆盖率工具,下载安装并使用时出现了点问题,于是就记录下来了。
Cobertura(西班牙语的覆盖)是一个和JUnit集成的代码覆盖率测量工具。Cobertura特性:1.免费,开源2.可以和ant和maven集成,也可以通过命令行调用2.可以生成HTML或者XML格式的报告3.可以按照不同的标准对HTML结果进行排序4.为每个类,包以及整个项目计算所覆盖的代码行与代码分支的百分比例
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 $*
为了测量测试覆盖率,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可以参考下面的这些内容:
[1]《JUnit 实战》Petar等人著,王魁译 ,Manning图书,人民邮电出版社
[2] 关于Bash---DOS到shell的转换:http://blog.csdn.net/xiajian2010/article/details/9790675