介绍Emma

EMMA 是一个用于检测和报告 JAVA 代码覆盖率的开源工具。它不但能很好的用于小型项目,很方便得得出覆盖率报告,而且适用于大型企业级别的项目。

EMMA 有许多优点,首先你能免费得到它,并把它用于自己项目的开发。它支持许多种级别的覆盖率指标:包,类,方法,语句块(basic block)和行,特别是它能测出某一行是否只是被部分覆盖,如条件语句短路的情况。它能生成 textxmlhtml 等形式的报告,以满足不同的需求,其 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

http://sourceforge.net/projects/emma/files/emma-release/2.0.5312/

Emma中文版Quick Start_Start

把这三个文件都下载下来,下载下来之后,当然是解压缩,解压缩emma-2.0.5312-lib.jar,我们得到emma.jar emma_ant.jar,将这两个文件放置到某个目录(譬如,我将其放置到D:\soft\emma)下。

补充说明:

这三个文件所包含的内容不同,emma-2.0.5312.zip包含文档 doc),示例(examples),以及运行时libemma.jar emma_ant.jar);emma-2.0.5312-src.zipemma的源码工程;emma-2.0.5312-lib.zip只包含运行时libemma.jar emma_ant.jar);

先来玩一下On the fly模式:

【开始】->【运行】,输入cmd,然后cdemma运行时包所在目录(我的是d:/soft/emma),然后运行:

java -cp emma.jar emmarun -jar C:\jdk1.6.0_22\demo\jfc\SwingSet2/SwingSet2.jar

此时,SwingSet2程序(有界面)跑起来了。随便玩一会该程序,然后关闭退出,此时,命令行窗口输出如下信息

EMMA: writing [txt] report to [D:\soft\emma\coverage.txt] ...

Emma在当前目录下输出了plain text格式的测试覆盖率报告,简单看一下coverage.txt的内容:

[EMMA v2.0.5312 report, generated Mon Aug 22 10:31:55 CST 2011]

-------------------------------------------------------------------------------

OVERALL COVERAGE SUMMARY:

 

[class, %] [method, %]     [block, %] [line, %]    [name]

97%  (121/125)!     50%  (253/510)!     71%  (14154/19842)!     66%  (2298.4/3493)!      all classes

 

OVERALL STATS SUMMARY:

 

total packages:        1

total classes:   125

total methods:         510

total executable files:      30

total executable lines:     3493

 

COVERAGE BREAKDOWN BY PACKAGE:

 

[class, %] [method, %]     [block, %] [line, %]    [name]

97%  (121/125)!     50%  (253/510)!     71%  (14154/19842)!     66%  (2298.4/3493)!      default package

-------------------------------------------------------------------------------

很不错,呵呵。

更进一步,我们还可以输出html格式的测试覆盖率报告,只需要给emmarun增加运行参数-r html即可:

java -cp emma.jar emmarun -r html -jar C:\jdk1.6.0_22\demo\jfc\SwingSet2/SwingSet2.jar

如果是生成html格式的报告,emma会在当前目录下生成coverage子目录,主页是coverage目录下的index.html

打开index.html,美中不足的是,我们没有看到跟源码结合,所展示出来的测试覆盖率的详细信息,像这样:

 

Emma中文版Quick Start_Start_02

别着急,emma很厉害,只要给emmarun增加一个参数:-sp C:\jdk1.6.0_22\demo\jfc\SwingSet2\src即可:

java -cp emma.jar emmarun -r html -sp C:\jdk1.6.0_22\demo\jfc\SwingSet2\src -jar C:\jdk1.6.0_22\demo\jfc\SwingSet2/SwingSet2.jar

这时,生成的html格式的覆盖率报告就能展示诸如上面这样丰富的覆盖率信息了,是不是很酷?sp其实就是source path的意思。

继续,再玩一下Offline 模式:

我们来尝试玩一下覆盖方式(overwrite)的离线插装。覆盖方式会把原来的jar 文件修改掉,所以,我们从拷贝一份SwingSet2.jar(我的是在C:\jdk1.6.0_22\demo\jfc\SwingSet2/SwingSet2.jarD:\soft\emma(避免直接修改jdk自带的SwingSet2.jar文件),然后:

java -cp emma.jar emma instr -m overwrite -cp SwingSet2.jar

回车后,控制台打印信息如下:

D:\soft\emma>java -cp emma.jar emma instr -m overwrite -cp SwingSet2.jar

EMMA: processing instrumentation path ...

EMMA: instrumentation path processed in 390 ms

EMMA: [138 class(es) instrumented, 235 resource(s) copied]

EMMA: metadata merged into [D:\soft\emma\coverage.em] {in 62 ms}

 

可见,emma还在当前目录下生成了元数据文件coverage.em。如果你想知道emma到底是怎么修改了jar包中的class文件,方法就是将原始jar包中的class文件(未用emma插装),和用 emma插装后的jar包中的class文件进行对比即可(当然得用winrarjar包解压缩,呵呵)。