zoukankan      html  css  js  c++  java
  • 使用Cobertura统计JUnit测试覆盖率

    这是一个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:Developcobertura-1.9.4.1加入环境变量path
     * @see 2)将要测试的应用代码、编译之后的class文件和所需jar拷到一个单独的目录中
     * @see   拷贝完毕后的目录结构为D:
    eportlib,D:
    eportsrc,D:
    eportin(含所有的class文件)
     * @see 3)在命令提示行中使用命令为要生成测试覆盖率报告的代码生成一个ser文件
     * @see   这一步主要的目的是为需要生成报告的class文件加入Cobertura标记,用来告诉Cobertura哪些文件需要生成测试覆盖率报告
     * @see   D:
    eportin>cobertura-instrument --destination instrumented com/jadyer/service
     * @see 4)基于ser文件运行测试
     * @see   这一步主要的目的是跑一便JUnit测试,并将测试结果加入到第三步所标记的相对应的class文件内,以便于下一步生成覆盖率报告
     * @see   D:
    eportin>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:
    eportin>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:Developcobertura-1.9.4.1cobertura-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张)


    生成报告前的目录结构如下

    生成报告前的目录结构


    生成报告后的目录结构如下

    生成报告后的目录结构


    生成的测试覆盖率报告首页截图

    生成的测试覆盖率报告首页截图


    最后一张图片是查看测试覆盖率详情的截图

    查看测试覆盖率详情

  • 相关阅读:
    javascript获取url地址问好后面的值,包括问号
    给Object扩展新方法
    关于hasOwnProperty()方法的应用
    javascript if 与 if else 的一点小认识
    express中路由设置的坑-----1
    javascript数组顺序-----1冒泡的另一种比较好理解的写法
    进程的控制与状态细化
    进程的定义与控制
    进程的定义与控制
    进程引入
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3181779.html
Copyright © 2011-2022 走看看