文档库 最新最全的文档下载
当前位置:文档库 › Emma(收集Java代码的覆盖率)

Emma(收集Java代码的覆盖率)

1内容

o引言功能测试中使用EMMA 的优点EMMA 在测试执行中的应用使用覆盖率报告总结和评估测试过程结论参考文献下载评论引言

EMMA 是一个开源、面向Java 程序测试覆盖率收集和报告工具。它通过对编译后的Java 字节码文件进行插装,在测试执行过程中收集覆盖率信息,并通过支持多种报表格式对覆盖率结果进行展示。EMMA 所使用的字节码插装不仅保证EMMA 不会给源代码带来“脏代码”,还确保EMMA 摆脱了源代码的束缚,这一特点使EMMA 应用于功能测试成为了可能。

注意:

?在测试中使用EMMA 收集覆盖率信息之前,需要从EMMA 的网站上下载emma.jar 包。在这个网站上还可以得到更多关于EMMA 的资源。

?EMMA 只能收集Java 代码的覆盖率。

测试覆盖率报告中未覆盖的部分也同样有价值:

?表明测试可能不完整,有些功能、代码没有被测试覆盖到。

?为测试用例的设计提供指导建议。在覆盖率报告的指导下,测试人员有目的地与开发人员进行讨论,确定未覆盖部分是测试的空白还是不需要测试的部分。

?帮助开发人员发现无用代码,为修改,完善代码提供依据。

?插装准备

在执行插装操作之前,首先应该扩展Java 虚拟机,即将emma.jar 放到被测组件运行使用的JRE 目录下面作为JRE 的扩展,以便EMMA 能够被调用。emma.jar 包含了EMMA 核心功能模块的实现和EMMA 运行时所需的类文件,这些文件是使用EMMA 所必需的。

由于示例被测组件运行在Websphere Portal Server 中,并使用默认的JRE 运行,因此将emma.jar 放到“/opt/WebSphere/PortalServer/java/jre/lib/ext” 下面。在实际的测试中,将该路径进行相应的替换。

插装

EMMA 中提供了“instr” 命令完成插装操作。插装操作可以面向JAR 包、WAR 包、WAR 包、类文件和目录,选择合适的命令进行插装可以使插装过程变得简便。下面的1-4通过具体例子介绍了不同情况下的插装命令。

1. 插装目录和类文件

对于类文件,通过指定类文件所在的目录实现。

清单 1. 对类文件插装命令

1. 插装JAR 包

JAR 包可以作为一个整体进行插装。通过对整个JAR 进行插装,可以避免对JAR 包进行解压和压缩的过程,提高插装效率。

清单 2. 对JAR 包插装命令

1. 插装WAR/EAR 包

由于WAR/EAR 包需要运行在特定的环境中,所以在进行插装之前,需要先将其安装在特定的J2EE 容器中,然后将其看作目录进行插装。

清单 3. 对WAR/EAR 包插装命令

1. 选择性的插装

EMMA 支持对整个JAR 包和目录进行插装,但如果在JAR 包或者目录中包含系统的文件或者测试过程中不关心的文件时,应该进行选择性插装,因为这些文件的存在会影响测试结果的百分比。EMMA 提供了选择插装的选项,实现选择性插装。

清单 4. 选择插装命令

上述命令选择了与清单2中同样的JAR 包,由于只包含了org.wstest.service.* 内的内容,因此只插装了4个类。

以上的1-4分别介绍了在插装过程中的常用命令,下面对命令中用到的一些参数进行解释。

参数“m”代表插装后文件输出的模式。有三个值可供选择:“copy” ,“overwrite” 和“fullcopy” 。其中,“copy” 和“ fullcopy” 这两种模式将会改变插装文件所在的目录,并需要测试人员手动为其生成所需的包,使用起来比较复杂。“overwrite” 模式直接用插装后的文件覆盖插装前文件,使用方便。但是由于同一时间生成的文件只能插装一次,在“overwrite”模式下,插装前的文件已经丢失,测试人员无法重复插装操作,因此建议在插装之前先将需要插装的文件和包进行备份。

参数“ip” 和“cp” 用来提供插装路径,其中“cp” 用来指明一个文件夹,“ip” 指定单独的文件或者JAR 包。

参数“Dmetadata.out.file” 用来指定插装得到的元数据文件保存的路径。

EMMA 中通过“ix” 参数指定文件的包含和排除关系,其中在“+” 符号后的文件为包含进的文件,“-” 后面的内容为排除在外的文件。

合并元数据

完成插装操作以后,在指定的路径下会产生一些名为“*coverage.em” 的文件,这些文件保存了插装的元信息,这些信息主要是记录插装过程中的插装点在被测代码中的位置。

如果在插装过程中,指定这些文件到同一文件的话,EMMA 默认将元数据进行合并。

如果测试人员未指定路径,或者希望得到独立的元文件,这些文件将分别产生在默认或指定的目录下。测试人员还可以通过使用“merge” 命令手动将这些元文件进行合并,保证生成的覆盖率报表的全面性。注意:合并操作不支持逆向操作。

清单 5. 合并元数据命令

在“input” 后面的参数为待合并的文件名,在“out” 后面的参数为合并以后的结果文件。

完成上面的操作以后,就已经完成了收集覆盖率信息的准备工作。接下来测试人员可以进行正常的测试工作,在运行测试的过程中,EMMA 将跟踪并记录执行轨迹,得到覆盖率信息。

运行测试用例,得到覆盖率报告

完成插装工作以后,测试人员可以按照测试计划运行测试用例。EMMA 将在测试执行的过程中记录代码执行信息并将结果记录在内存中。每次当JVM 停止时,内存中记录的执行信息将被清除并被保存到“*.ec” 的文件中。但是在实际测试的过程中,JVM 的

停止很难控制,因此测试人员可以定时手动将内存中执行信息写出。在这种情况下,内存中的记录被输出,但是内存中的内容不被清除。清单5-7介绍了收集覆盖率信息以及生成覆盖率信息报告的命令。

清单 6. 从远程机器上收集覆盖率信息

清单7. 从本地收集覆盖率信息

这样收集到的信息被保存在“coverage.ec” 中,“coverage.ec” 是二进制格式的文件,因此很难被用来查看覆盖率结果。

清单8. 生成覆盖率报告

在生成覆盖率报告的过程中,测试人员可以根据测试要求通过“Dreport.metrics” 参数设定满意的覆盖率标准。在示例命令中设定了类覆盖率的满意度为80%。

测试报告可以以HTML ,文本和XML 三种格式输出。图1、图2为HTML 格式的报告的例子。覆盖率的报告是以包、类、方法三级单位组织的。图1是Index 类的执行情况,其中红颜色代表该覆盖率未达到满意的覆盖率标准。图2则是包

org.numberquiz 中QuizBran 类的执行情况,从总体看,类覆盖率为100%,方法为91%。在附录中可以看到示例程序完整的测试覆盖率报告。

图 1. Index 测试报告

图 2. QuizBran 测试报告

在功能测试过程中,为每个单独的测试用例生成独立的覆盖率报告能够给测试过程带来很大的帮助:

当测试用例失败或者抛出异常时,可以通过覆盖率报告找到该测试用例对应的代码,这样就可以为测试人员提供可能出错代码的范围。这一报告不仅可以帮助测试人员在提交问题时更加详细的描述错误,提供更详细的信息,还可以为开发人员跟踪问题提供线索,缩短解决问题的周期。

?测试人员可以从独立的测试报告中获得代码和功能模块的对应关系,更好的理解测试用例的作用。

?独立的测试报告可以帮助测试人员改进测试用例的设计,删除重复的测试用例,将覆盖点较多的测试用例进行拆分。

为得到独立的测试报告,需要在每次执行测试用例前,将内存中的执行信息清除。目前有两种方法支持清除记录,测试人员可在测试过程中,根据需要选择合适的方法。

?每次运行完一个测试用例,重启JVM 。这种方法能够完整的清除内存中记录的执行信息,但是每次重启JVM 给测试带来很多麻烦。

?使用“coverage.reset” 命令,该命令可以在不重启JVM 的情况下,清除内存中记录的方法、块、行的执行信息,但是无法清除类覆盖信息。如果用户关注的重点在方法的覆盖信息上,可以选择这种方法。

清单9. 清除内存中覆盖率信息命令

合并覆盖率结果

完成所用的测试用例后,测试覆盖信息可以被合并在一起,得到整个测试的覆盖报告。

覆盖率结果文件通过“merge” 命令合并“*.ec” 文件实现的。

另外,由于EMMA 中测试覆盖率是通过与“*.em” 文件关联获得代码信息的,因此当代码发生变化时,已经运行过的测试不必完全重复,只需将得到的“*.ec” 文件合并(新得到的“*.ec” 文件放在后面),然后关联最新的“*.em” 文件即可得到代码变化后的覆盖率信息,这方便了EMMA 支持版本变化的测试。在生成新的测试报告的时候,需要注意“*.ec” 的时间一定要晚于“*.em” 文件。

清单9. 合并覆盖率结果命令

?测试人员忽略的部分。

?测试用例设计中被覆盖而测试执行中未覆盖的部分。

?程序中的无用代码。

例如:在实际的测试过程中,发现一个叫syslog.messages 包的覆盖率一直很低,一些类和方法始终没有被覆盖到。在测试执行过程中,与这些类相关的结果也没有出现。

因此,在与开发人员确认后,发现对这些内容的调用在写代码的时候被遗忘了(图3中红色框中的内容)。

图 3. 覆盖率报告分析

改进测试设计

利用覆盖率报告,测试人员可以改进测试用例的设计:

?移除覆盖范围重复的测试用例。

?对于覆盖点过多的测试用例,可以进行拆分,保证测试用例具有针对性。?对于测试中未覆盖的部分,增加测试用例保证测试完整性。

相关文档