8

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

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

EclEmma 说它只被部分覆盖,尽管我有一个单元测试,其中一个线程可以访问而另一个线程被阻塞。

是否有可能使用 EclEmma 全面覆盖同步?

我可以以某种方式对代码进行注释以告诉 EclEmma 全面覆盖这一行吗?

亲切的问候罗杰

4

3 回答 3

7

我不确定是否有可能获得全面报道,因为issue 2939804报告:

EMMA 始终标记synchronized(..)部分覆盖

例子:

synchronized (lock) // partially covered (yellow line in EclEmma)
{
// ...
}
synchronized (this) // partially covered (yellow line in EclEmma)
{
// ...
}

也许不同的工具(如 Cobertura)会产生不同的结果?(我最近没有测试过)。


2012 年 12 月更新(2 年多后):

Nathan D Ryan 报告

synchronized如果同步块包含在对象监视器上等待的代码,并且测试中断等待线程,则将亮为绿色。

经过一点实验,如果块正常完成并由于异常而突然完成,我能够实现对synchronized线路的完全覆盖。synchronized

于 2010-09-15T06:38:35.430 回答
1

EclEmma 在下面使用 Jacoco 进行覆盖率分析。

正如 Jacoco 的(当前不存在的)JAVAC.SYNC 过滤选项中所解释的,该行为是为同步块生成的字节码的结果:

Java 同步块被编译成两条字节码指令:MONITORENTER 位于块的开头, MONITOREXIT 位于块的末尾。

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

一个相关的Jacoco 问题 245解释了如何触发异常以达到完全覆盖,如果这是需要的,@nathan-ryan 也解释了这一点:

  1. 正常执行同步块的一项测试
  2. 第二个测试从同步块中抛出(并因此期望)异常。
于 2016-06-01T11:18:40.543 回答
0

我相信问题是MyClass.class显然是使用

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

由于隐藏的 Class.forName() 导致的隐式分支。这种情况很不幸,因为它很常见,但程序员几乎无法控制它。

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

我在第一次通读时错过了这一点。

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

/罗杰

于 2010-09-15T07:48:06.683 回答