Cobertura自动化测试

 

       公司最近要提高代码质量,让所有的项目从今往后必须要提高Unit Test的覆盖率到二成,测试才给测。这可让兄弟们到吸了一口凉气,我想这玩意还不把人给整死,郁闷了老半天。

还好,偶经高人指点,知道了Cobertura这个开源的工具。“Open source”作为一个程序员来说,,最喜欢听到的英文单词就是这两个了。Cobretura是一个基于JCoverage的分支开源项目,它的主要用途在于进行单元测试代码覆盖率的自动化测试。总的来说通过它,我们可以一定程度来了解我们代码的质量。一般来说单元测试覆盖率越高的代码越可靠。当然这不是绝对的,但是我相信有比没有好,就好比有计划比没计划好,即使计划烂到无法实施。

好了罗嗦了老半天就开始讲正题了。假如现在有个Java项目要进行单元测试代码的覆盖率的计算(由于Cobertura是基于java,所以这里讨论的仅为java项目)。

我们按部就班吧。

1.      下载http://cobertura.sourceforge.net/download.html,最新版是1.9.4.1。下载好了后找到如下几个jar包:cobertura.jar,asm-3.0.jar, asm-tree-3.0.jar, jakarta-oro-2.0.8.jar, log4j-1.2.9.jar,把它们拷贝到Java项目的根目下的lib/cobertura目录(如果没有lib和其子目cobertura就新建它们)。

2.      在项目中添加antbuild_Coverage.xml脚本和所用的属性文件build_Coverage.properties。内容如下:

build_Coverage.properties

 

build_Coverage.xml

   

 

 

 

添加好了后只要修改好参数,然后通过eclipse执行ant的脚本,等待其跑完即可。

 

在这里有几点要注意的:

一)参数的修改

  • cobertura-instrument进行单元测试代码的指定,如,

<fileset dir="${classes.dir}">

  • 在执行Junit的ant脚本部分指定单元测试代码的路径,如,

<batchtest todir="${reports.xml.dir}" unless="testcase">

<fileset dir="${src.test.dir}">

  • 在report部分指定要统计覆盖率的java代码的位置,如,

<cobertura-report datafile="${reports.dir}/basic_coverage.ser" srcdir="${src.main.dir}" destdir="${coverage.xml.dir}" format="xml" />

  • 指定cobertura计算coverage的时候要用的的ser文件

<sysproperty key="net.sourceforge.cobertura.datafile" file="${reports.dir}/basic_coverage.ser" />

二)如果你想要去掉几个不想进行统计的package的话,你可以如下操作

        

     上面去掉了包名中有mock的和po的所有类,这样的话可以让你仅统计你关心的package

 三)下面的classpath引用的顺序不能乱,不然会出所有的line coverage0的现象。

<junit fork="yes"  failureProperty="test.failed" printsummary="on" haltonfailure="false">
			<!--
					Specify the name of the coverage data file to use.
				-->
			<sysproperty key="net.sourceforge.cobertura.datafile" file="${reports.dir}/basic_coverage.ser" />

			<!--
					Note the classpath order: instrumented classes are before the
					original (uninstrumented) classes.  This is important.
				-->
			<classpath location="src/main/resources"/>
			<classpath location="${instrumented.dir}" />
			<classpath location="${classes.dir}" />

			<!--
					The instrumented classes reference classes used by the
					Cobertura runtime, so Cobertura and its dependencies
					must be on your classpath.
				-->
			<classpath refid="cobertura_classpath" />
			<classpath refid="run.classpath" />


四)这里再进一步对instrument进行一个说明,在执行junit test case之前必须生成cobertura的instrument类,这里些类是你要进行统计覆盖率的所有类的class文件,也就是如下这一段ant script

<cobertura-instrument datafile="${reports.dir}/basic_coverage.ser"todir="${instrumented.dir}" >
                     <!--
                                   Thefollowing line causes instrument to ignore any
                                   sourceline containing a reference to log4j, for the
                                   purposesof coverage reporting.
                            -->
                     <ignoreregex="org.apache.log4j.*" />
 
                     <filesetdir="${classes.dir}">
                            <!--
                                          Instrumentall the application classes, but
                                          don'tinstrument the test classes.
                                   -->
                            <includename="**/*.class" />
                            <excludename="**/mock/**/*.class"/>
                            <excludename="**/po/**/*.class"/>
                            <excludename="**/*Test.class" />
                            <excludename="**/Js*Run.class"/>                         
                     </fileset>
              </cobertura-instrument>

这里你应该要明确一点,也就是生成到instrument.dir目录下的类的class文件与classes.dir下同名的class已经不再是原来的class, 实际上经过instrument这个过程后已经打个了cobretura的标记信息,从如下图可以看出(同一个类instrument后的内容与之前做的比较)

在后面真正要执行junit的时候,如果你不想看到你的覆盖率报表显示的是0,所用到的类必须先引用instrument的类。如下所示:

       

<!--
                  Note the classpath order: instrumented classes arebefore the
                  original (uninstrumented) classes.  This is important.
              -->
           <classpath location="src/main/resources"/>
           <classpath location="${instrumented.dir}" />
           <classpath location="${classes.dir}" />
 
           <!--
                  The instrumented classes reference classes used bythe
                  Cobertura runtime, so Cobertura and itsdependencies
                  must be on your classpath.
              -->
           <classpath refid="cobertura_classpath" />
           <classpath refid="run.classpath" />

虽然后面classes.dir中包含有同名的class,但这个从报表结果上看来,在加载过instrument的类后,其原始类就不再加载了。所以你也完全可以把原始类从classes.dir中去掉再放到junit的classpath,这个过程是没有问题的。除此之外还有一个地方需要注意的是在执行junit的ant script时候,要设置一下fork=”true”,也就是启用一个新的jvm来跑所有的test case。当然你也可以把fork=”true”放在batchtest的属性中。表相上得知如果运行ant的jvm来执行test case的话会产生类的冲突。所以只能启用新的jvm来完成cobertura下的test case运行。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值