当前位置: 首页 > 知识库问答 >
问题:

使用EclEmma和Eclipse获取“未收集覆盖率数据”消息

洪弘亮
2023-03-14

我最近有一个非常烦人的问题不知从哪里冒出来。在启用EclEmma覆盖的情况下运行我的单元测试会导致从Eclipse弹出以下对话框窗口:

对于搜索引擎,其内容如下:

在此覆盖会话期间没有收集覆盖数据。
请不要从Eclipse手动终止Java进程。

我的项目中没有提供任何类的覆盖信息。不用说,我不会手动终止Java过程。为了尝试修复它,我重新导入了我的项目,升级了Java,重新安装了Emma,重新启动了我的Macbook Pro,确保临时文件系统空间看起来不错,还有其他20件我现在忘记的事情。

我终于注意到只有我的几个开源项目产生了这个错误,并决定减少我的一个测试。这是重现问题的最小测试。

我正在尝试覆盖的测试类:

public class Foo {
    public void method() {
        System.out.println("hello");
    }
}

下面是驱动它的junit类:

public class EclEmmaFailureTest {
    @Test(timeout = 100000) // if you remove the timeout it works
    public void testStuff() {
        // this should cover Foo 100%
        new Foo().method();
        // if you comment this out stuff works
        org.apache.commons.logging.LogFactory.getLog(getClass());
    }
}

测试中的commons loglog引用似乎破坏了覆盖率集合。我已在以下网址发布了一份有效回购协议:https://github.com/j256/eclemma-failure

如果您执行以下任一操作,问题就会消失:

  • 注释掉日志工厂。getLog(getClass())调用

我正在运行Emma版本3.1.3,我的测试程序依赖于共享日志记录版本1.2。

我有一个降级路径来解决这个问题,并让我再次工作,但JUnit4.12有安全问题。我很好奇是否有人知道导致这种情况的junit或emma的具体问题。

雅各科也受到了影响,这并不奇怪。这是升级到JUnit 4.13.1之前的覆盖率报告,显示80%的覆盖率,之后没有可用的覆盖率信息显示0%。

谢谢

共有2个答案

燕钟展
2023-03-14

这里不使用EMMA,即使名称EclEmma可能暗示它。事实上,EclEmma始于2006年,是EMMA的Eclipse集成。但是9年多前,自从EclEmma 2.0以来,EMMA已经被JaCoCo取代,JaCoCo是一个由EclEmma团队创建的免费Java代码覆盖库。

由于应用程序和/或测试中的代码更改会使问题消失,因此不太可能收集但不显示覆盖数据。因此,唯一可能剩下的原因是有什么东西干扰了JaCoCo收集数据。JaCoCo的常见问题解答指出了这可能是什么:

为什么一个类显示为未被覆盖,尽管它已经被执行了?

首先确保已收集执行数据。为此,请选择HTML报告右上角的Sessions链接,并检查是否列出了有问题的类。如果已列出但未链接,则执行时的类是另一个类文件。确保在运行时使用与生成报表完全相同的类文件。请注意,某些工具(例如EJB容器、模拟框架)可能会在运行时修改类文件。有关详细讨论,请参阅关于类ID的章节。

为了确保这不是缓存问题,请尝试一下,如果一个小的代码更改也能解决这个问题。

您列出的解决问题的方法非常不同,但都可能会影响时间,这将表明并发问题。您可以尝试更改测试的顺序和/或在某些地方添加Thread.sleep(),看看这是否会改变什么。

但是,在您的情况下,根本原因是不清楚的,没有最小的可重复性示例(如果是并发问题,可能很难提供)。

更新:

正如Evgeny Mandrikov指出的,根本问题实际上是JUnit 4.13和4.13的并发问题。1(包括所有4.13-beta-*和4.13-rc-*版本,但JUnit的早期版本不受影响):

JUnit 4问题#1652:不应该销毁超时线程组

这个问题已经为即将发布的JUnit4.13修复。2释放。

以下可作为一种解决方法,以防止线程组被破坏,从而JaCoCo丢失其收集的数据(通过向该组中添加虚拟线程):

/** Workaround for already fixed JUnit 4 issue #1652 (<https://github.com/junit-team/junit4/issues/1652>) */
public static void workaround_for_junit4_issue_1652() {
    String version = junit.runner.Version.id();
    if (!"4.13.1".equals(version) && !"4.13".equals(version))
        fail("Workaround for JUnit 4 issue #1652 required for JUnit 4.13 and 4.13.1 only; actual version: "
           + version);
    Thread thread = Thread.currentThread();
    if (!"Time-limited test".equals(thread.getName())) fail("Workaround only required for a test with a timeout.");
    new Thread(thread.getThreadGroup(), new Runnable() {
        @Override
        public void run() {
            try {
                while (!thread.isInterrupted()) Thread.sleep(100);
            } catch (InterruptedException e) {}
        }
    }).start();
}

@Test(timeout = 42)
public void test() {
    workaround_for_junit4_issue_1652();
    // ...
}
欧阳博超
2023-03-14

在此覆盖率会话期间未收集覆盖率数据。请不要从Eclipse手动终止Java进程。

这似乎是4.13版本中引入的线程组周围的JUnit问题。看到这个github讨论,看到这个拉请求。当设置超时时,JUnit似乎一直在破坏线程组来处理卡住的线程问题,这并没有给Eclemma机会写出覆盖信息。他们似乎已经将线程组更改为守护线程,作为处理此问题的更好方法。

看来唯一的解决办法是等待4.13。2从4.13之前的版本开始发布。我有安全问题。

看起来关闭挂钩在4.13中的执行方式与在4.12中的执行方式不同,因此覆盖失败。

感谢Eclemma邮件列表在这方面的帮助。

 类似资料:
  • 我是jUnit的新手,我试图加深我对它的了解。我在网上搜索了一下,但没有找到任何可以解决几个疑问的东西。 这是代码: 这是jUnit4测试用例: TestCase运行正常,没有任何问题,但我有两个简单的问题/问题: 1) 只测试方法的正确功能是正确的,还是应该同时测试值和/或任何特定异常? 2) 当我用EclEmma运行代码覆盖率时,它给了我75%的代码覆盖率,因为测试用例没有测试类的构造函数。测

  • 我刚刚在eclipse中安装了Eclemma,并创建了一个JUnit测试。我运行了测试,它成功了,绿色和红色的横幅显示在我的程序中,但我看不到任何“覆盖率”视图,如所示的指令(也不在窗口显示视图中)。 我如何解决这个问题?我必须重写我的JUnit测试还是重新安装EclEmma? 谢谢

  • 问题内容: 我们正在将EasyMock和PowerMock与JUnit一起使用。使用的覆盖率工具是ECLEmma。使用EasyMock,它会以绿色正确显示覆盖范围(已覆盖)。但是,对于使用PowerMock进行了单元测试的代码,覆盖范围显示为红色(未覆盖)。在网络上阅读过类似的问题。但是,只想检查是否有解决方案。 谢谢 Venkatesh 问题答案: 这是一个已知的问题:https : //git

  • 我正试图使用Eclipse和EclEmma在java中覆盖我的代码。 我的测试使用JUnit 4,我有一些测试看起来像这样: EclEmma说测试失败是因为抛出了一个IllegalArgumentExc0019。所以它会丢弃我的代码覆盖率指标,即使它应该抛出一些东西。有没有一个选项可以让它看到JUnit期望的异常标签? 编辑:我发现,如果您将抛出添加到测试声明中,它也可以工作!

  • 在Mocha的帮助下,我最近开始为我的节点项目进行单元测试。到目前为止一切进展顺利,我发现我的代码有了显著的改进,因为我考虑了测试中要涉及的所有角度。 现在,我想和我团队的其他人分享我的经验,让他们开始自己的测试。我想分享的部分信息是我的代码实际上被覆盖了多少。 下面是我的应用程序结构示例,我已将其分为不同的组件或模块。为了促进重用,我试图将所有依赖项保持在最低限度,并与组件文件夹隔离。这还包括保

  • 我在单元测试中使用ByteBuddy重新定义类。我在每次测试后重置类,以确保测试之间没有串扰。 只要在EclipseIDE中运行测试,或者使用maven命令行运行,ByteBuddy就可以正常工作。但如果它在Eclipse中运行并覆盖,重置该类会导致以下异常: 下面是一个示例测试,它通过默认的JUnit运行程序,但在Eclipse中使用代码覆盖运行时失败。下面是失败的完整堆栈跟踪。 我使用的是By