【问题标题】:Set JUnit timeout in eclipse在eclipse中设置JUnit超时
【发布时间】:2011-05-05 02:41:35
【问题描述】:

问题

当我使用 eclipse 运行所有 JUnit 测试时,我可以设置默认超时吗?

背景

我的经理坚持编写有时需要 5 分钟才能完成的单元测试。当我尝试运行我们的整个测试套件(只有大约 300 个测试)时,可能需要 30 多分钟。我想放置一些东西来停止任何需要超过 10 秒的测试。

我知道可以对单个测试进行注释:

@Test(timeout=10000)

但是这样做会使他的长时间测试总是失败。当他在他的盒子上运行它们时,我希望它们能够工作(如果我必须在签入之前对项目进行细微调整,这是可以接受的。但是,从 40 个不同的测试文件中删除超时是不切实际的)。

我也知道我可以创建一个 ant 任务来为所有测试设置默认超时,如下所示:

<junit timeout="10000">
  ...
</junit>

问题在于,我们通常使用 右键单击 > 运行方式 > JUnit 测试从 Eclipse 内部运行测试

总结

那么有没有一种相对轻松的方法来为所有测试设置超时,可能使用运行配置设置、项目设置、JUnit 首选项、环境变量等?我什至会安装一些其他插件,让我可以右键单击特定的测试文件夹并以其他方式运行所有测试,例如通过 ant 或其他方式...

【问题讨论】:

  • 测试需要 5 分钟?听起来他们要么在每个测试中做太多 far 要么他们是集成测试而不是单元测试......
  • 您可以将集成测试与 junit-tests 分开。长时间运行的测试应该在像 hudson 这样的构建服务器上运行,而不是在本地机器上。
  • @Donal:不幸的是,它们是单元测试。我不喜欢他们。我不同意他们的看法。然而,我对他们无能为力。因此我的问题......我的目标是,至少,消除我盒子上的问题。我想我要写一个切面来用@test(timeout=10)注释所有的测试方法。然后,我永远不会将这方面检查到 Subversion 中。这是我的计划,我想……
  • 方面方法不起作用,因为这些方法已经有一个@Test 注释,并且目前在 AspectJ 中没有替换注释的机制。 .. 不过,我认为它正在开发中。
  • @Test(timeout=10) 表示超时 10 毫秒 而不是 10 秒

标签: java eclipse unit-testing junit timeout


【解决方案1】:

我的经理坚持要编写有时需要 5 分钟才能完成的单元测试

这几乎肯定表明这些测试实际上不是单元测试。删掉Gordian knot:尝试重构您的测试套件以提供等效的测试覆盖率,而无需运行那么长时间的测试用例。

【讨论】:

  • 可悲的是,它们单元测试。他验证低级函数在失败 5 分钟后超时。 :( 该函数有 3 行代码。
  • 使用超时需要一个时钟。真正的代码将使用系统时钟,但您的单元测试不需要。将时钟抽象为一个对象,并使用依赖注入来消除对系统时钟的直接依赖。即不直接调用系统时钟函数,而是引入一个Clock接口(或抽象基类)传递给超时代码。对于单元测试,使用模拟超时的MockClock(即IS-A Clock)。对于真正的集成代码,使用调用系统时钟函数的SystemClock(即IS-A Clock)。
  • 虽然他不用时钟,但我明白你的意思。在这种情况下,超时实际上是基于失败的库调用(最终在 I/O 期间超时)。如果他嘲笑那个电话会很好,但他没有。我不能真正改变他所有的测试,在我认为合适的地方使用模拟。所以我一直在寻找一种方法来为所有测试设置超时。这些天,我们又开始使用 ant,所以我可以使用 junit 任务中内置的超时,正如我在原始帖子中提到的那样。蚂蚁很棒。
【解决方案2】:

听起来测试套件会帮助你。

您可以拥有两个测试套件; QuickTestsAllTests。在 AllTests 套件中包含 QuickTests,以及需要很长时间的测试。然后所有其他测试将进入快速测试套件。

在 Eclipse 中,您可以一次运行整个测试套件。因此,您将运行 QuickTests,这样所有其他慢速测试都不会运行。

see this question 了解如何将超时应用于套件,该套件将应用于套件中的嵌套套件和类。结合我上面的建议,哪个可以达到你想要的效果。

【讨论】:

    【解决方案3】:

    如果您想将测试配置为最多运行十秒钟,您可以试试这个:

    @Test(timeout=10000)

    【讨论】:

    • 谢谢,但此解决方案不适用于原始问题中描述的情况:doing this would make his long tests always fail. I want them to work when he runs them on his box . . . deleting the timeouts from 40 different test files [before checkin] is not practical
    【解决方案4】:

    可能的解决方案: 从另一个类扩展您的所有测试类:例如TestBase

    添加到TestBase 全局超时。此超时将应用于所有扩展类:

    public class TestBase {
        @Rule
        public Timeout globalTimeout = new Timeout(10000);
    }
    

    【讨论】:

    • 这是一个很好的建议。绝对可以在其他情况下使用的东西。但在这种情况下,需要更改他的所有测试,这不是一个选择。
    • 不错的技巧,但有没有办法为扩展该类的特定测试(例如只有一个)覆盖该值?
    • 当然。您可以在测试类中的特定方法上使用@Test(timeout=10)
    【解决方案5】:

    因此,将 Infinitest 与启用的“慢速测试警告”与过滤功能结合使用可能会起到作用。您可以识别超出时间限制的测试并将它们添加到过滤器列表中,这只会影响 Eclipse 内部的测试。通过 CLI/CI 等可能的构建脚本运行测试根本不会受到影响。 您可以在此处找到有关设置的更多信息:http://improvingworks.com/products/infinitest/infinitest-user-guide/

    【讨论】:

    • 这看起来棒极了!几乎正是我正在寻找的东西,以及在其他情况下我可以经常使用的东西。我会试试这个,如果它有效,我就被卖了......
    【解决方案6】:

    几乎可以肯定,您的老板测试是伪装成单元测试的系统测试。如果它们应该是单元测试并且速度很慢,则应该将它们重构为使用模拟,以便它们运行得更快。

    无论如何,比在这件事上与你的老板对抗更务实和外交的方法可能是自己尝试跑得更快。我在一个项目中看到了一个 hack 来做到这一点,其中慢速测试的名称中有 SytemTest。然后在构建文件中创建了两个 ant 目标。一个运行所有测试,一个按类名过滤掉 SytemTests 。要实现这一点,您所要做的就是重命名一些测试并编写您的 ant 目标。

    【讨论】:

      【解决方案7】:

      我知道这并不能真正回答你的问题,但简单的答案是不要!

      有条件地设置超时是错误的,因为你会在你的机器上进行单元测试,你总是会失败。单元测试的重点是能够快速看到你没有破坏任何东西。必须检查失败的测试列表以确保它只是长时间运行的测试,这会使一些错误通过裂缝。

      正如一些评论者所提到的,您应该将测试拆分为运行快速的单元测试和运行较慢的集成测试,即为您的代码提供一个名为 src/main/java 的源文件夹,为单元测试提供一个名为 src/test/java 的源文件夹和 src/integration-test/java 用于更长时间运行的测试。

      【讨论】:

      • 感谢您抽出宝贵时间回答,但您正在向合唱团讲道;)我 100% 同意您的观点,但我不能做出这样的改变。所以我的问题更多是关于中和糟糕的单元测试的影响。
      • @gmale:我们都去过那里,伙计,但如果你不继续对你的老板保持警惕,一切都不会改变。快速浏览了 Ant 源代码,他们应用的超时不是 JUnit 的事情。您可能希望将 @Ignore 用于您不想运行的特定测试,而不是任意超时。您可以做的一件事是编辑 JUnit 源代码以设置默认超时。您必须更改您使用的 JUnit 库。
      • 这将更适合作为评论。
      猜你喜欢
      • 1970-01-01
      • 2018-02-13
      • 2021-08-22
      • 2015-02-13
      • 2013-07-17
      • 1970-01-01
      • 2015-10-28
      • 2023-03-12
      • 1970-01-01
      相关资源
      最近更新 更多