Cobertura使用说明
诸葛卜霸
2023-12-01
Cobertura 通过被测试的行数和被测试的分支数来计算覆盖率。第一次测试时,两种测试方法之间的差别并不是很重要。Cobertura 还为类计算平均 McCabe 复杂度.
并不总是可以得到完美的、100% 的代码覆盖率。有时您会发现,不管对代码如何改造,仍然有一些行、方法、甚至是整个类是测试不到的。下面是您可能会遇到的挑战的一些例子:
* 只在特定平台上执行的代码。例如,在一个设计良好的 GUI 应用程序中,添加一个 Exit 菜单项的代码可以在 Windows PC 上运行,但它不能在 Mac 机上运行。
* 捕获不会发生的异常的 catch 语句,比如在从 ByteArrayInputStream 进行读取操作时抛出的 IOException。
* 非公共类中的一些方法,它们永远也不会被实际调用,只是为了满足某个接口契约而必须实现。
* 处理虚拟机 bug 的代码块,比如说,不能识别 UTF-8 编码。
考虑到上面这些以及类似的情况,我认为一些极限程序员自动删除所有未测试代码的做法是不切实际的,并且可能具有一定的讽刺性。不能总是获得绝对完美的测试覆盖率并不意味着就不会有更好的覆盖率。
然而,比执行不到的语句和方法更常见的是残留代码,它不再有任何作用,并且从代码基中去掉这些代码也不会产生任何影响。有时可以通过使用反射来访问私有成员这样的怪招来测试未测试的代码。还可以为未测试的、包保护(package-protected)的代码来编写测试代码,将测试类放到将要测试的类所在那个包中。但最好不要这样做。所有不能通过发布的(公共的和受保护的)接口访问的代码都应删除。执行不到的代码不应当成为代码基的一部分。代码基越小,它就越容易被理解和维护。
一.环境:
1.将Cobertura.jar文件放置到Jboss的X:\jboss-4.0.5.GA\server\default\lib目录下
2.由于我们将Test类也加入了Cobertura的Instrument所以在运行Test类时需要Cobertura支持,将cobertura.jar放到工程中
3.运行库在X:\Cobertura\1.9下
注意:会话Bean的远程和本地接口必需加上接口名
例如:
@Stateless
@Remote(AdministratorManager.class)
@Local(AdministratorManager.class)
public class AdministratorManagerBean
implements AdministratorManager{}
二.原理:
将IDEA编译好的Class文件加入Cobertura的字节码(不会对接口进行修改),执行修改过的字节码,记录信息在cobertrua.ser文件中,在Jboss运行期间执行Junit测试,会执行修改后的class文件,将信息在Jboss停止后写入Jboss bin目录下的cobertura.bar文件,然后将前后两次生成的Cobertura.ser文件合,将合并后的文件进行分析生成报告.
三.应用
1.重新编译整个工程
2.deploy
将IDEA生成的Class文件,加入Cobertura字节码后,进行替换
3.将Cobertura修改过的字码进行打包
4.部署工程执行测试代码
5.停止Jboss,执行合并操作,交JBoss生成的和根据源码生成的.ser文件合并
6.生成报告
100%覆盖率的因原是只按照Jboss运行期间生成cobertura.ser文件生成的报告
0%的原因是生成的cobertura.ser文件是最初加入instrument的ser文件未经过服务器或加入字码的文件进行修改.
异常:
解决方法:会话Bean中的Local和Remote加入接口名
java.lang.RuntimeException: Use of empty @Remote on bean class and there are more than one default interface
at org.jboss.ejb3.ProxyFactoryHelper.getRemoteInterfaces(ProxyFactoryHelper.java:358)
at org.jboss.ejb3.ProxyDeployer.initializeRemoteBindingMetadata(ProxyDeployer.java:132)
at org.jboss.ejb3.SessionContainer.instantiated(SessionContainer.java:109)
at org.jboss.ejb3.Ejb3Deployment.deployElement(Ejb3Deployment.java:415)
at org.jboss.ejb3.Ejb3Deployment.deployElement(Ejb3Deployment.java:397)
at org.jboss.ejb3.Ejb3Deployment.deployUrl(Ejb3Deployment.java:378)
at org.jboss.ejb3.Ejb3Deployment.deploy(Ejb3Deployment.java:350)