介绍测试代码覆盖率的重要性
测试驱动开发(TDD)是极限编程的一个重要特点,它具有很多优点,并被越来越多的开发人员所接受。在测试驱动开发过程中,程序员经历了编写测试用例,实现功能,重构代码这个不断迭代的过程。实践证明,这个过程能显著提高我们的生产效率,并产生高质量的代码。它还能给我们以自信,让我们放心的重构自己的代码。
测试代码确实能够保证代码的质量,但如果你以为自己已经写了一堆测试用例,并都能运行通过时,就能高枕无忧了,那么你错了。隐藏的 Bug 也许只是在等待时机让你的系统崩溃。这是什么原因呢?聪明的你肯定已经想到,测试代码是用来保证功能代码的质量的,但测试代码的质量如何,我们不得而知。我们需要知道,我们辛苦编写的测试代码到底覆盖了多少功能代码,这就是我写这篇文章的出发点,我将介绍一种测试代码覆盖率的工具 - EMMA。
介绍 EMMA
EMMA 是一个用于检测和报告 JAVA 代码覆盖率的开源工具。它不但能很好的用于小型项目,很方便得得出覆盖率报告,而且适用于大型企业级别的项目。
EMMA 有许多优点,首先你能免费得到它,并把它用于自己项目的开发。它支持许多种级别的覆盖率指标:包,类,方法,语句块(basic block)和行,特别是它能测出某一行是否只是被部分覆盖,如条件语句短路的情况。它能生成 text,xml,html 等形式的报告,以满足不同的需求,其 html 报告提供下钻功能,我们能够从 package 开始一步步链接到我们所关注的某个方法。EMMA 能和 Makefile 和 Ant 集成,便于应用于大型项目。特别还须指出的一点是,EMMA 的效率很高,这对于大型项目来说很重要。
EMMA 是通过向 .class 文件中插入字节码的方式来跟踪记录被运行代码信息的。EMMA 支持两种模式:On the fly 和 Offline 模式。
On the fly 模式往加载的类中加入字节码,相当于用 EMMA 实现的 application class loader 替代原来的 application class loader。
Offline 模式在类被加载前,加入字节码。
On the fly 模式比较方便,缺点也比较明显,如它不能为被 boot class loader 加载的类生成覆盖率报告,也不能为像 J2EE 容器那种自己有独特 class loader 的类生成覆盖率报告。这时,我们能求助于 Offline 模式。
EMMA 也支持两种运行方式:Command line 和 Ant。
命令行一般和 On the fly 模式一起适用,对于简单的项目能够快速产生覆盖率报告。通过 Ant task 来运行 EMMA 的话,特别适用于大型的项目。
本文后面提供的实例主要是演示如何集成 EMMA 和 Ant,通过 Offline 模式产生覆盖率报告。
示例项目
示例工程 SampleProject 是个小型的项目,有一个类 NumberParser,主要功能是把一个字符串解析成 float 型。下面是整个工程的目录结构。
图1. 示例项目的目录结构