为什么EclEmma不能同步(MyClass.class)?

时间:2010-09-15 06:34:45

标签: java concurrency code-coverage synchronized emma

我正在使用EclEmma进行覆盖率分析。

我的Java代码包含synchronized(MyClass.class){}块。

EclEmma说它只是部分覆盖,事件虽然我有一个单元测试,其中一个线程获得访问权限而另一个线程被阻止。

是否可以使用EclEmma完全覆盖同步?

我可以用某种方式注释代码来告诉EclEmma让这条线完全覆盖吗?

亲切的问候 罗杰

3 个答案:

答案 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年后):

Nathan D Ryan reports

  如果synchronized块包含在对象监视器上等待的代码,并且测试中断等待的线程,则

synchronized将亮起绿色。

     

经过一些实验,如果synchronized块正常完成并由于异常而突然完成,我就能够完全覆盖synchronized行。

答案 1 :(得分:1)

EclEmma使用Jacoco进行覆盖分析。

如Jacoco(目前不存在)JAVAC.SYNC filtering option中所述,行为是为同步块生成的字节代码的结果:

  

Java同步块被编译成两个字节码指令:开头的MONITORENTER和块结尾的MONITOREXIT。

     

为了确保在任何情况下释放监视器,安装了指向另一个MONITOREXIT指令的异常处理程序。此异常处理程序块通常会导致部分行覆盖,从源代码的角度来看这是没有意义的。

相关Jacoco issue 245解释了如果需要,可以触发例外以达到完全覆盖范围,@ nathan-ryan也解释了这一点:

  1. 通常执行同步块的一个测试
  2. 在同步块中抛出(并因此预期)异常的第二个测试。

答案 2 :(得分:0)

我认为问题是MyClass.class,显然是使用

实现的

http://emma.sourceforge.net/faq.html#q.fractional.examples

  

由隐藏的Class.forName()引起的隐式分支。这个案子是   相当不幸,因为它很常见,但程序员   几乎无法控制它。

     

因为Class.forName()可以抛出已检查的异常,所以编译器   发出一个catch块,在未经检查的情况下重新抛出它们。这个拦截块   几乎没有在实践中执行,但它成功地标记了线   部分覆盖。

我在第一次阅读时错过了。

我会尝试重新编写代码以获得全面覆盖。

/罗杰