本文共 3810 字,大约阅读时间需要 12 分钟。
作为一个测试人员,保证产品的软件质量是其工作首要目标,为了这个目标,测试人员常常会通过很多手段或工具来加以保证,覆盖率就是其中一环比较重要的环节。
我们通常会将测试覆盖率分为两个部分,即“需求覆盖率”和“代码覆盖率”。
以上两者完全可以相辅相成,用代码覆盖结果反向的检查需求覆盖(用例)的测试是否充分完整。
java中比较流行的代码覆盖率工具有EMMA,Cobertura,jacoco等。其实以现在情况来看,使用jacoco的人群是比较多的,有点大势所趋的感觉。
本来以前用EMMA的人很多,但是开发这个工具的坑爹团队自从2006年后就再也没更新过了
可以理解为EMMA已die。java项目大多都是用maven管理的,如果我们想统计单元测试的覆盖率的话,通过emma与maven集成是最简单不过的。不像jacoco那么麻烦,配置emma十分简单。只需要添加如下依赖:
org.codehaus.mojo emma-maven-plugin 1.0-alpha-3 true
然后运行命令:mvn emma:emma。 之后你就可以看report了
如果你使用jenkins作为CI的工具的话,其实就更简单了。你都不用再pom文件中增加依赖,安装好EMMA的插件以后,直接运行上面的例子的命令就好了。
上面介绍的都只能统计项目本身的测试,也就是在工程中的src/test/java包下面的测试脚本。如果是我们的接口测试,UI测试呢?我们怎么做才能统计代码覆盖率呢?这就需要一些手段了。
首先,你需要从官网中下载emma.jar到你的测试环境中,然后copy到你的jre的ext文件夹中。这样就是扩展了java命令,以后你就可以直接以java emma的形式执行操作了。
然后你需要对被测的包进行插桩。然后emma会开启一个服务,默认端口47653。这个服务就会监控被测的工程了。插桩的例子如下。具体的命令参数大家参照官网就好。java emma instr -m overwrite -cp simba-1.0.jar -out coverage.em
最后就是收集报告了。这里需要两个命令,一个是收集数据,一个是生成报告。例子如下。着重说一下几个参数。-sp是你源代码的路径,这样emma才能获取代码信息展示更详细的报告。-in是生成报告需要的元数据信息。是在插桩和收集数据生成的中间文件。-r是report的格式。这几个参数是常用的。
java emma ctl -connect localhost:47653 -command coverage.get,coverage.ecjava emma report -r html -Dreport.out.encoding=utf-8 -sp /opt/web/simba/src/main/java -in coverage.em,coverage.ec
只要你不删除插桩和收集数据所产生的元数据文件的话。你都可以累计的生成报告。还有一个merge模式可以合并报告,详细的东西大家可以去官网看一下。EMMA的好处就是使用简单。最后我发一个生成的报告的图吧。
EMMA有一个坑就是在jdk1.6以上的版本有可能出现一个问题,插桩之后运行会出现一个classformat异常。提示你参数数量不正确,大概是这个意思吧。其实这是jdk在1.7以后使用的验证器不一样了。而EMMA这个坑爹货太久没有更新了,根本没cover到新版本的JDK。所以需要我们在启动jvm的时候增加一个参数。-XX:-UseSplitVerifier。这样就可以了。这个坑当时着实坑了我俩小时。
jacoco就是 EMMA 的团队开发的 他们已经全部转向jacoco
很多第三方的工具提供了对JaCoCo的集成,如sonar、Jenkins等。
JaCoCo包含了多种尺度的覆盖率计数器,包含指令级覆盖(Instructions,C0coverage),分支(Branches,C1coverage)、圈复杂度(CyclomaticComplexity)、行覆盖(Lines)、方法覆盖(non-abstract methods)、类覆盖(classes)行覆盖率:度量被测程序的每行代码是否被执行,判断标准行中是否至少有一个指令被执行。
类覆盖率:度量计算class类文件是否被执行。
分支覆盖率:度量if和switch语句的分支覆盖情况,计算一个方法里面的
总分支数,确定执行和不执行的 分支数量。
方法覆盖率:度量被测程序的方法执行情况,是否执行取决于方法中是否有至少一个指令被执行。
指令覆盖:计数单元是单个java二进制代码指令,指令覆盖率提供了代码是否被执行的信息,度量完全 独立源码格式。
圈复杂度:在(线性)组合中,计算在一个方法里面所有可能路径的最小数目
只针对 class 文件,并不需要源文件
JVM中通过-javaagent参数指定特定的jar文件启动Instrumentation的代理程序,代理程序在通过Class Loader装载一个class前判断是否转换修改class文件,将统计代码插入class,测试覆盖率分析可以在JVM执行测试代码的过程中完成。
在测试前先对文件进行插桩,然后生成插过桩的class或jar包,测试插过桩 的class和jar包后,会生成动态覆盖信息到文件,最后统一对覆盖信息进行处理,并生成报告。
On-the-fly模式更方便简单进行代码覆盖分析,无需提前进行字节码插桩,无需考虑classpath 的设置。
存在如下情况不适合on-the-fly,需要采用offline提前对字节码插桩:
(1)运行环境不支持java agent。
(2)部署环境不允许设置JVM参数。
(3)字节码需要被转换成其他的虚拟机如Android Dalvik VM。
(4)动态修改字节码过程中和其他agent冲突。
(5)无法自定义用户加载类。
JaCoCo执行最小需要Java5
JaCoCo通过注入来修改和生成java字节码,使用的是ASM库。
不再赘述
这种方式适合Maven的项目。
调用流程:
(1) 项目已jar包方式打包,引入junit和jacoco。 (2) Build时执行instrument、report、check。 (3) 覆盖率生成到target/jacoco.exec转载地址:http://ylfsf.baihongyu.com/