我正在使用EclEmma进行覆盖率分析。
我的Java代码包含一个synchronized(MyClass.class) {}块。
EclEmma说它只覆盖了一部分,虽然我有一个单元测试,其中一个线程获得访问,另一个线程被阻塞。
是否有可能使用EclEmma全面覆盖synchronized?
我可以用某种方式注释代码,告诉EclEmma完全覆盖这一行吗?
亲切地问候罗杰
发布于 2010-09-15 14:38:35
我不确定是否有可能获得完整的覆盖范围,因为issue 2939804报道:
EMMA始终将
synchronized(..)标记为部分覆盖的
示例:
synchronized (lock) // partially covered (yellow line in EclEmma)
{
// ...
}
synchronized (this) // partially covered (yellow line in EclEmma)
{
// ...
}也许不同的工具(like Cobertura)会产生不同的结果?(我最近没有测试过它)。
更新2012年12月(两年多后):
如果synchronized块包含在对象监视器上等待的代码,并且测试中断等待线程,则
synchronized将亮起为绿色。
经过一些实验之后,如果synchronized块正常完成并且由于异常而突然完成,我能够实现synchronized行的完全覆盖。
发布于 2016-06-01 19:18:41
EclEmma在下面使用Jacoco进行覆盖率分析。
正如Jacoco的(目前不存在) JAVAC.SYNC filtering option中所解释的,该行为是为同步块生成的字节代码的结果:
同步块被编译成两个字节码指令: MONITORENTER在块的开头,MONITOREXIT在块的结尾。
为确保在任何情况下释放监视器,安装了指向另一个MONITOREXIT指令的异常处理程序。此异常处理程序块通常会导致部分行覆盖,从源代码的角度来看,这是没有意义的。
一个相关的Jacoco issue 245解释了如何触发异常以达到完全覆盖,如果需要的话,@nathan-ryan也解释了这一点:
发布于 2010-09-15 15:48:07
我认为问题出在MyClass.class,它显然是使用
http://emma.sourceforge.net/faq.html#q.fractional.examples
由于隐藏的Class.forName(),
隐式分支。这种情况相当不幸,因为它很常见,但程序员几乎无法控制它。
因为Class.forName()可以抛出已检查的异常,所以编译器会发出一个catch块,将它们作为未检查的异常重新抛出。这个catch块在实践中几乎不会执行,但它成功地将该行标记为部分覆盖。
在第一次通读时,我错过了这一点。
我将尝试重写我的代码,以获得完整的覆盖范围。
/Roger
https://stackoverflow.com/questions/3715213
复制相似问题