使用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:\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张)
生成报告前的目录结构如下

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

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

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

使用Cobertura统计JUnit测试覆盖率的更多相关文章
- 统计代码测试覆盖率-Python
衡量Unit Test(单元测试)是否充分, 覆盖率是一个必要指标, 是检验单元测试的重要依据, 这里针对python unittest 的单元测试覆盖率coverage进行分享. 来自官方的解释: ...
- 由cobertura插件生成测试覆盖率报告
由于cobertura已经集成到maven中,所以可以很方便的直接调用此插件生成报告: 直接运行命令:mvn cobertura:cobertura 就可以直接生成测试报告了. 下面是截图:
- spring && Cobertura && maven &&junit 单元测试以及测试覆盖率
1. 目的: junit 单元测试,Cobertura 测试覆盖率报告 项目目录结构 2. maven 配置 <project xmlns= ...
- 用 Cobertura 测量测试覆盖率
尽管测试先行编程(test-first programming)和单元测试已不能算是新概念,但测试驱动的开发仍然是过去 10 年中最重要的编程创新.最好的一些编程人员在过去半个世纪中一直在使用这些 ...
- 白盒测试笔记之:Junit 单元测试以及测试覆盖率
单元测试: 单元测试是从代码层面验证代码的正确性. 一般考虑接口中的数据结构是否正确,变量的临界条件,如空字符串,空集合等. Junit入门 参考: Junit 入门教程: https://ww ...
- 统计 Django 项目的测试覆盖率
作者:HelloGitHub-追梦人物 文中所涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 我们完成了对 blog 应用和 comment 应用这两个核心 app 的测试.现在 ...
- 测试覆盖率 之 Cobertura的使用
什么是代码覆盖率? 代码覆盖率是对整个测试过程中被执行的代码的衡量,它能测量源代码中的哪些语句在测试中被执行,哪些语句尚未被执行. 为什么要测量代码覆盖率? 众所周知,测试可以提高软件版本的质量和可预 ...
- 测试覆盖率工具:EclEmma
测试覆盖率工具:EclEmma 2016-08-26 目录 1 测试覆盖率实现技术2 EclEmma介绍3 EclEmma测试覆盖率指标4 EclEmma安装5 示例项目介绍 5.1 创建项目 5 ...
- Maven运行JUnit测试(http://www.360doc.com/content/13/0927/15/7304817_317455642.shtml)
Maven单元测试 分类: maven 2012-05-09 15:17 1986人阅读 评论(1) 收藏 举报 maven测试junit单元测试javarandom 目录(?)[-] maven ...
随机推荐
- java设计模式之十桥接模式(Bridge)
桥接模式就是把事物和其具体实现分开,使他们可以各自独立的变化.桥接的用意是:将抽象化与实现化解耦,使得二者可以独立变化,像我们常用的JDBC桥DriverManager一样,JDBC进行连接数据库的时 ...
- 如何判断微信内置浏览器(通过User Agent实现)
在进行微信公众账号开发的时候,其中很大一块是微站点的开发,我们需要知道当前的浏览器是微信内置的浏览器,那么如何判断呢? 微信内置浏览器的 User Agent 如何判断微信内置浏览器,首先需要获取微信 ...
- yii性能调节
网络应用程序的性能受很多因素的影响.数据库存取,文件系统操作,网络带宽等都是潜在的影响因素. Yii 已在各个方面减少框架带来的性能影响.但是在用户的应用中仍有很多地方可以被改善来提高性能. 1. 开 ...
- linuxsocket通信recv研究缓存机制
曾有过这样一个小疑问.当一个进程注册的插座后,,假设插座没有被调用recv函数接受包.能接受到数据包吗? 或者这样说,假设我的程序注冊了一个套接字去接受数据包,可是每收到一个数据包都须要非常长 ...
- UC编程:输入输出重定向(标准IO)
[c] #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; char szBuf[100]; /* 将屏 ...
- javascript 函数介绍
javascript函数使用的时候,往往都比较单一,这里介绍几种不同于我们之前使用的函数调用方式! 1.函数表达式包含名称,用于递归 var f = function s(num) { if (num ...
- 基于EF+WCF的通用三层架构及解析
分享基于EF+WCF的通用三层架构及解析 本项目结合EF 4.3及WCF实现了经典三层架构,各层面向接口,WCF实现SOA,Repository封装调用,在此基础上实现了WCFContext,动态服务 ...
- sugarcrm关于邮件设置几个不好理解的地方
陈沙克日志 把我的过程记录下来,以免以后忘了 2008-06-11 12:32 sugarcrm关于邮件设置几个不好理解的地方 最近看sugarcrm的使用,别的基本使用,没有什么问题,几天就 ...
- Win7下Redmine2.0.3+Mysql55+Ruby1.8.7成功安装记录分享
准备软件: Ruby 下载网页: http://rubyforge.org/frs/?group_id=167&release_id=46836 http://files.rubyforge. ...
- JAVA中ClassPath妙用
初学java的人肯定都配置过java三大环境变量 . JAVA_HOME:JDK目录 PATH:jdkbin目录 jre目录 CLASSPATH:一般指向类库lib,也可自定义使用 以下例子是个小例 ...