如何在JUnit 5中超过超时后使测试失败?

2022-09-02 19:49:24

在 JUnit 4 中,“超时”注释参数可用于强制测试在给定时间后停止:

@Test(timeout=100)
public void infinity() {
   while(true);
}

如何在JUnit 5中做到这一点?

注释类型测试的超时参数密切相关(以及从中获取的代码),但对于 JUnit 5。


答案 1

该属性的严格等效项是声明性批注。
来自 JUnit 5 文档timeout@Timeout

该注释允许声明,如果测试、测试工厂、测试模板或生命周期方法的执行时间超过给定的持续时间,则该方法应失败。持续时间的时间单位默认为秒,但可配置。@Timeout

例如:

@Test
@Timeout(value = 100, unit = TimeUnit.MILLISECONDS)
void infinity() { 
  // fails if execution time exceeds 100 milliseconds
  //...
}

Assertions.assertTimeout()Assertions.assertTimeoutPreemptively() 是 JUnit 5 中引入的新概念(在 JUnit 4 中不存在)。这些是将超时缩小到一组特定语句的替代方法:这些语句在或传递的 as 参数中定义。
这两种方法(名称非常接近)解决了相同的总体目标,但有细微的区别。
如果超时发生,则以抢占方式中止 超时,而实际上并没有发生超时。
要实现超时,将执行在与调用代码不同的线程中提供的,同时在同一线程中执行。@TimeoutExecutableSupplierassertTimeoutPreemptively()Executable/SupplierassertTimeout()assertTimeoutPreemptively()Executable/SupplierassertTimeout()

来自官方文档的警告:依赖于用于测试执行设置/拆卸的存储的代码/库可能会产生不良的副作用,因为它在不同的线程中执行提供的语句。java.lang.ThreadLocalassertTimeoutPreemptively()


答案 2

使用来自 的静态断言:assertTimeoutPreemptivelyorg.junit.jupiter.api.Assertions

@Test
public void infinity() {
    assertTimeoutPreemptively(Duration.ofMillis(100), () -> {
        while (true);
    });
}

推荐