这是一个JavaProject,关于Cobertura的用法详见代码注释
首先是应用代码(即被测试的代码)
package com.jadyer.service; public class CalculatorService { public int add(int a, int b) { return a + b; } public int minus(int a, int b) { return a - b; } public int multiply(int a, int b) { return a * b; } public int divide(int a, int b) { if (0 == b) { throw new IllegalArgumentException("非法参数:除数不能为零.."); } return a / b; } }
下面是采用JUnit4.x编写的测试代码
package com.jadyer.service; import org.junit.Assert; import org.junit.Test; /** * 使用Cobertura统计JUnit测试覆盖率 * @see ---------------------------------------------------------------------------------------------------------- * @see 生成测试覆盖率报告有三种方式(Maven--Ant--命令行) * @see Cobertura下载地址为http://sourceforge.net/projects/cobertura/files/ * @see Cobertura结合Maven使用起来是极为方便的,详见http://blog.csdn.net/jadyer/article/details/7658734 * @see Cobertura结合Ant生成报告也是非常方便的,详见本文下方给出的build.xml * @see 最麻烦的就是用命令行(不推荐) * @see ---------------------------------------------------------------------------------------------------------- * @see 通过命令行生成报告 * @see 0)先交待下工程的目录结构,src下存放应用代码,test下存放测试代码,bin下存放应用代码和测试代码的class文件 * @see 1)解压cobertura-1.9.4.1-bin.zip到本地硬盘,并将D:\Develop\cobertura-1.9.4.1加入环境变量path * @see 2)将要测试的应用代码、编译之后的class文件和所需jar拷到一个单独的目录中 * @see 拷贝完毕后的目录结构为D:\report\lib,D:\report\src,D:\report\bin(含所有的class文件) * @see 3)在命令提示行中使用命令为要生成测试覆盖率报告的代码生成一个ser文件 * @see 这一步主要的目的是为需要生成报告的class文件加入Cobertura标记,用来告诉Cobertura哪些文件需要生成测试覆盖率报告 * @see D:\report\bin>cobertura-instrument --destination instrumented com/jadyer/service * @see 4)基于ser文件运行测试 * @see 这一步主要的目的是跑一便JUnit测试,并将测试结果加入到第三步所标记的相对应的class文件内,以便于下一步生成覆盖率报告 * @see D:\report\bin>java -cp ../lib/junit-4.10.jar;../lib/cobertura.jar;instrumented;.;-Dnet.source * @see forge.cobertura.datafile=cobertura.ser org.junit.runner.JUnitCore com.jadyer.service.CalculatorServiceTest * @see 5)根据ser文件生成测试覆盖率报告 * @see 这一步主要的目的是生成报告,同时关联第三步所标记的class文件的源码 * @see D:\report\bin>cobertura-report --format html --datafile cobertura.ser --destination reports ../src * @see 这里面有两点需要注意一下 * @see 1)如果测试代码的包名与应用代码的包名相同(事实上这很正常),那么通过以上5步所生成的报告中,会有一点无伤大雅的小问题 * @see 那就是报告中即含有应用代码的测试覆盖率报告(它会按照实际覆盖率显示),也含有测试代码的测试覆盖率报告(它会显示100%) * @see 产生这一结果主要在于上面的第三步操作,由于包名相同故它会将测试代码的class也纳入报告标记的范围内 * @see 我曾试过为它加入--excludeClasses参数,发现竟没有效果,可能我哪里没写对,不深究了,反正以后也没打算用命令行 * @see 不过用本文提供的Ant脚本就不会出现这个问题了(Ant脚本中的<exclude name="/>是起作用的) * @see 2)若文件编码为UTF-8,则生成的报告中可能会乱码,此时只需为cobertura-report.bat增加-Dfile.encoding=UTF-8参数即可 * @see 即为D:\Develop\cobertura-1.9.4.1\cobertura-report.bat文件里面的java命令加上此参数即可 * @see ---------------------------------------------------------------------------------------------------------- * @create Jul 6, 2013 6:18:16 PM * @author 玄玉<http://blog.csdn.net/jadyer> */ public class CalculatorServiceTest { @Test public void myAdd() { int result = new CalculatorService().add(1, 2); Assert.assertEquals(3, result); } @Test public void myMinus() { int result = new CalculatorService().minus(1, 2); Assert.assertEquals(-1, result); } @Test public void myMultiply() { int result = new CalculatorService().multiply(2, 3); Assert.assertEquals(6, result); } @Test public void myDivide() { int result = new CalculatorService().divide(6, 5); Assert.assertEquals(1, result); } // @Test(expected = IllegalArgumentException.class) // public void myDivideException() { // new CalculatorService().divide(6, 0); // } }
下面附上我所使用的Ant脚本
<?xml version="1.0" encoding="UTF-8"?> <project name="cobertura.junit.report" default="coverage" basedir="."> <!-- 这是一个JavaProject,目录结构属很典型的,即src下存放应用代码,test下存放测试代码,bin下存放应用代码和测试代码的class文件 --> <property name="dir.lib" location="lib"/> <property name="dir.src" location="src"/> <property name="dir.test" location="test"/> <!-- 将生成测试覆盖率报告的有关文件都统一放到report目录下 --> <property name="dir.report" location="report"/> <!-- 将生成测试覆盖率报告时所生成的JUnit测试报告也统一放到report目录下 --> <property name="dir.report.junit" location="report/junit"/> <!-- 将生成测试覆盖率报告所需的应用代码和测试代码的class也统一放到report目录下 --> <property name="dir.report.class" location="report/class"/> <!-- 存放测试覆盖率报告结果的目录,最后浏览该目录下的index.html就能看到报告了 --> <property name="dir.report.result" location="report/result"/> <!-- 用于存放生成测试覆盖率报告时所需的被Cobertura标记过的应用代码class文件的目录 --> <property name="dir.report.instrument" location="report/instrument"/> <!-- 指明下面<javac/>时需用到的jar包,这里最基本的需要用到下面6个jar --> <!-- junit-4.10.jar --> <!-- cobertura.jar(取自下载到的cobertura-1.9.4.1-bin.zip) --> <!-- asm-3.0(取自下载到的cobertura-1.9.4.1-bin.zip中的lib目录) --> <!-- asm-tree-3.0(取自下载到的cobertura-1.9.4.1-bin.zip中的lib目录) --> <!-- jakarta-oro-2.0.8(取自下载到的cobertura-1.9.4.1-bin.zip中的lib目录) --> <!-- log4j-1.2.9(取自下载到的cobertura-1.9.4.1-bin.zip中的lib目录) --> <path id="app.classpath"> <fileset dir="${dir.lib}"> <include name="*.jar"/> </fileset> </path> <!-- 配置Cobatura ant扩展任务(其实这个tasks.properties是位于lib/cobertura.jar中的) --> <taskdef classpathref="app.classpath" resource="tasks.properties"/> <target name="init"> <delete dir="${dir.report}"/> <mkdir dir="${dir.report.junit}"/> <mkdir dir="${dir.report.class}"/> <mkdir dir="${dir.report.instrument}"/> </target> <!-- 同时编译应用代码和测试代码 --> <target name="compile" depends="init"> <javac srcdir="${dir.src}:${dir.test}" destdir="${dir.report.class}" debug="true" encoding="UTF-8"> <classpath refid="app.classpath"/> </javac> </target> <!-- 生成测试覆盖率报告(期间会进行JUnit测试) --> <target name="coverage" depends="compile"> <cobertura-instrument todir="${dir.report.instrument}"> <ignore regex="org.apache.log4j.*"/> <!-- 指定需要生成代码覆盖率报告的class --> <fileset dir="${dir.report.class}"> <include name="**/**.class"/> <exclude name="**/*Test.class"/> </fileset> </cobertura-instrument> <!-- printsummary表示是否打印基本信息,haltonfailure表示测试失败是否中止,fork必须启用,可设置为"on,true,yes"等--> <junit printsummary="on" haltonerror="on" haltonfailure="on" fork="on"> <!-- instrumented classes should be before the original (uninstrumented) classes --> <classpath location="${dir.report.instrument}"/> <classpath location="${dir.report.class}"/> <classpath refid="app.classpath"/> <!-- 同时运行多个测试用例,todir用来存放测试的输出结果,如果不指定<formatter/>是不会输出结果到todir中的 --> <formatter type="plain"/> <batchtest todir="${dir.report.junit}"> <fileset dir="${dir.report.class}"> <include name="**/*Test.class"/> </fileset> </batchtest> </junit> <!-- srcdir指定被测试的Java源码目录,destdir指定存放生成的报告的目录(默认就会生成html格式的报告) --> <cobertura-report srcdir="${dir.src}" destdir="${dir.report.result}"/> <!-- 最后将ser文件统一备份到报告目录中(默认的会在build.xml的同一目录下生成cobertura.ser) --> <move file="cobertura.ser" todir="${dir.report}"/> </target> </project>
最后把项目的目录结构和生成的测试覆盖率报告贴一下图(共4张)
生成报告前的目录结构如下
生成报告后的目录结构如下
生成的测试覆盖率报告首页截图
最后一张图片是查看测试覆盖率详情的截图