用 Cobertura 测量测试覆盖率
1. Cobertura 简介
cobertura 在西班牙语是覆盖的意思,Cobertura 是一种开源工具,它通过检测基本的代码,并观察在测试包运行时执行了哪些代码和没有执行哪些代码,来测量测试覆盖率。除了找出未测试到的代码并发现 bug 外,Cobertura 还可以通过标记无用的、执行不到的代码来优化代码。
cobertura 的基本工作思路就是:
(1) 对已经编译好的class 文件添加日志代码
(2) 对添加好日志的代码进行单元测试
(3) 输出覆盖率统计报告
统计报告是html 格式的,其中标出每行源码是否执行,非常直观。
所以我们在ant 中使用cobertura 的步骤就是:
(1) 编译代码
(2) 定义 cobertura 的ant task
(3) 用 cobertura-instrument 命令为编译好的代码添加日志
(4) 用 junit 命令对添加好日志的代码进行单元测试
(5) 用 cobertura-report 命令输出报告
2. 例子
(1) 建立目录结构
cobertura
|-- src
|----|-- test
|----|----|--cobertura
|----|----|----|--AddInt.java
|----|----|----|--unittest
|----|----|----|----|--AddIntTest.java
|-- lib
|----|-- asm-2.2.1.jar
|----|-- cobertura.jar
|----|-- jakarta-oro-2.0.8.jar
|----|-- junit-3.8.1.jar
|----|-- log4j-1.2.9.jar
|-- build
|----|-- build.xml
用到的包除了junit 都可以在下载的 cobertura 包中得到
(2) 写代码:
AddInt.java 和 AddIntTest.java
// AddInt.java
package test.cobertura;
public class AddInt {
public int add(int i, int j){
int m = i + j;
return m;
}
}
// AddIntTest.java
package test.cobertura.unittest;
import test.cobertura.AddInt;
import junit.framework.TestCase;
public class AddIntTest extends TestCase {
AddInt addInt = null;
public AddIntTest() {
super();
}
protected void setUp() throws Exception {
super.setUp();
addInt = new AddInt();
}
protected void tearDown() throws Exception {
super.tearDown();
addInt = null;
}
public void testAdd() {
assertEquals(3, addInt.add(1, 2));
}
}
(3) 写build.xml
运行build.xml 后我们在build 目录下会得到如下目录结构:
build
|-- src-classes //编译源码的目标目录
|-- instrumented-classes //cobertura 添加日志的代码就放在这里
|-- junit-report //junit 生成的测试报告
|-- cobertura-report //cobertura 生成的统计报告
<?xml version="1.0" encoding="UTF-8"?>
<project name="cobertura_test" basedir="." default="coverage-report">
<property name="src.home" value="../src" />
<property name="lib.home" value="../lib" />
<property name="src_classes" value="${basedir}/src-classes" />
<property name="instrumented_classes" value="${basedir}/instrumented-classes" />
<property name="junit_report" value="${basedir}/junit-report" />
<property name="cobertura_report" value="${basedir}/cobertura-report" />
<path id="lib_path">
<fileset dir="${lib.home}">
<include name="*.jar" />
</fileset>
</path>
<path id="src_classes_path">
<path refid="lib_path" />
<pathelement location="${src_classes}" />
</path>
<path id="instrumented_classes_path">
<path refid="lib_path" />
<pathelement location="${instrumented_classes}" />
</path>
<target name="init" depends="clean">
<mkdir dir="${src_classes}" />
<mkdir dir="${instrumented_classes}" />
<mkdir dir="${junit_report}" />
<mkdir dir="${cobertura_report}" />
</target>
<target name="clean">
<delete dir="${src_classes}" />
<delete dir="${instrumented_classes}" />
<delete dir="${junit_report}" />
<delete dir="${cobertura_report}" />
</target>
<target name="compile_src" depends="init">
<javac srcdir="${src.home}" destdir="${src_classes}" debug="true">
<classpath>
<path refid="lib_path" />
</classpath>
</javac>
</target>
<target name="junit_test" depends="compile_src">
<junit printsummary="yes" fork="yes" haltonfailure="yes">
<classpath>
<path refid="lib_path" />
<path refid="src_classes_path" />
</classpath>
<formatter type="xml" />
<test name="test.cobertura.unittest.AddIntTest" />
</junit>
</target>
<target name="junit_report" depends="junit_test">
<junitreport todir="${junit_report}">
<fileset dir=".">
<include name="TEST-*.xml" />
</fileset>
<report format="frames" todir="${junit_report}/reports/html" />
</junitreport>
</target>
<!-- 定义 cobertura 的ant task -->
<taskdef classpath="cobertura.jar" resource="tasks.properties" classpathref="lib_path" />
<!-- 为源码添加日志代码,放到 instrumented-classes 目录 -->
<target name="instrument">
<cobertura-instrument todir="${instrumented_classes}">
<fileset dir="${src_classes}">
<include name="**/*.class" />
</fileset>
</cobertura-instrument>
</target>
<!-- 执行单元测试 -->
<target name="cover-test" depends="instrument">
<junit printsummary="yes" fork="yes" haltonfailure="yes">
<classpath>
<path refid="instrumented_classes_path" />
<path refid="src_classes_path" />
</classpath>
<formatter type="xml" />
<test name="test.cobertura.unittest.AddIntTest" />
</junit>
</target>
<!-- 输出报告 -->
<target name="coverage-report" depends="junit_report,cover-test">
<cobertura-report srcdir="${src.home}" destdir="${cobertura_report}" />
</target>
</project>
运行 ant, 成功后就可以到 cobertura-report 下看覆盖率报告了。
irini
2007-02-13 16:14:33
评论:1
阅读:262
引用:0
不用ant调用怎么直接运行Cobertura阿?
@2008-04-09 09:29:50 66
不用ant调用怎么直接运行Cobertura阿?
