代码覆盖率测试
代码覆盖测试概括:
一般来讲,会分为插桩,执行和报告三个过程。
代码覆盖率测试常用的统计数据:
1. 行覆盖率
2. 分支覆盖率
代码覆盖率的作用:
1. 清晰的知道哪些代码未被测试过,和developer商量在未被测试的代码中哪些需要进行测试
2. 衡量测试用例质量的重要标准之一
如何看代码覆盖率统计报告:
1. 不要过分的看重统计数据,即使覆盖率是100%,也不能保证该代码没有bug。
例子:
我们的代码
package com.vanward.coverage.example01;
public class PathCoverage{
public String pathExample(boolean condition){
String value = null;
if(condition){
value = " " + condition + " ";
}
return value.trim();
}
}
我们测试的case:
当condition=true时,执行该代码
我们覆盖率测试结果:
Line Coverage:100%
Branch Coverage:100%
但当condition=false时,我们的代码就会 throw exception.
2. 我们可以关心覆盖率很低的代码,来根据需要补充我们的case,但不避过分追求100%的报告
下面主要介绍覆盖率测试工具的使用,这次只介绍EMMA coverage tool
1. Coverage tool for Java Program:EMMA
EMMA之所以入选,一它是完全开源的,免费的,二它包含了覆盖工具的大部分功能,且不需要任何扩展lib的支持,三我只学习了它
1.1 EMMA工作原理:
EMMA 是通过向 .class 文件中插入字节码的方式来跟踪记录被运行代码信息的
1.2 EMMA的版本
目前有两个版本比较流行,2.0和2.1
2.0中的命令有:
-bash-3.00# java emmaemma usage: emma <command> [command options],
where <command> is one of:
run application runner {same as 'emmarun' tool};
instr offline instrumentation processor;
report offline report generator;
merge offline data file merge processor.
{use '<command> -h' to see usage help for a given command}
[EMMA v2.0, build 5312]
2.1中的命令有:
比2.0多了个ctl命令,这个命令主要是用来将EMMA收集到的coverage running data 主动的导出到文件中;2.0版本是当程序自然退出或通过Ctrl-C退出时,才将coverage running data 导出到文件中。
这里主要讲2.0
1.3 EMMA支持的两种方式
1.3.1 on-the-fly
On the fly 模式往加载的类中加入字节码,相当于用 EMMA 实现的 application class loader 替代原来的 application class loader。1.3.2 offline
On the fly 模式比较方便,缺点也比较明显,如它不能为被 boot class loader 加载的类生成覆盖率报告,也不能为像 J2EE 容器那种自己有独特 class loader 的类生成覆盖率报告。这时,我们能求助于 Offline 模式。
这里,我们主要介绍offlien mode
1.4 EMMA收集的统计数据类型
EMMA 收集的数据包括类覆盖率、方法覆盖率、块覆盖率和行覆盖率。作为功能测试,我们可以将重心放到类覆盖率和方法覆盖率上,对块覆盖率和行覆盖率可以作为我们的参考。
1.5 工作方式
包含命令行和Ant两种方式
这里先介绍命令行方式
1.6 安装
它的安装很简单。首先从http://emma.sourceforge.net/index.html下载2.0版本的zip包,解压后,将emma.jar 放到jdkhome/jre/lib/ext下面。
1.7 命令行
一般命令行会通过三个步骤来完成:插桩(instr),运行,报告(report)
EMMA命令行的格式是:emma command -option
1.7.1 Instr
这个是插桩的命令,在程序启动前进行。我们会发现,插桩后,我们的class文件明显的增大了。这是EMMA把它的测试代码插入到我们的class文件里了
它的参数包括:
-
-ip, -cp, -instrpath
...instrumentation path
-
指定
插桩的路径,允许带多个值,每个值用逗号分割。
cp 用来指明一个文件夹,ip用来指明单独的文件或jar包
-
-d, -dir, -outdir
directory
- The location to store instrumented class files (in
fullcopy
mode instrumented classes are stored indestdir
/classes
and instrumented archives are stored indestdir
/lib
subdirectories, respectively). Ignored if-m
isoverwrite
. -
-out, -outfile
metadata file
- The location to store class coverage metadata (default: file
coverage.em
in the current directory). Neither particular file name nor extension are required. -
-merge (
y[es]
|n[o]
) - This flag indicates whether the metadata should be merged into the destination
-out
file, if any (default:true
). Any existing data is clobbered otherwise. -
-m, -outmode (
copy
|overwrite
|fullcopy
) -
Specifies the instrumentation output mode. Valid values for this property are:
copy
(default): copy only instrumented class files and archive entries intodestdir
directory.overwrite
: overwrite input class files and archives.fullcopy
: copy all (instrumented or not) class files and archives todestdir
/classes
anddestdir
/lib
, respectively.
-
-ix, -filter
...filter patterns
用来指定class的包含和排除关系。+是包含,-是排除
例子:
java emma.jar emma instr -ip ../test.jar -m overwrite -ix -com.test.* -Dmetadata.out.file=/test/test.em
1.7.2 运行我们的程序,程序自然退出后,会在当前目录下产生coverage.ec文件,这个文件就是前面说到的存放coverage running data的文件,我们需要*.em and *.ec (metadata and coverage running data) 两个文件来生成report
1.7.3 report
它的参数包括:
-in, -input
... meta/coverage data files
指定 metadata和coverage data 的目录
-
-r, -report (
...txt
|html
|xml
) - 生成报告的类型
-
-sp, -sourcepath
...list of source directories
-
指定java文件的路径。这个对后面的html report会起到作用。会链接到相应的java文件,并通过颜色标识哪些语句被执行过,哪些语句没有执行。