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