简体   繁体   English

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

[英]How to fail a test after a timeout is exceeded in JUnit 5?

In JUnit 4 the "timeout" annotation parameter can be used to force a test to stop after the given amount of time:在 JUnit 4 中,“timeout”注释参数可用于强制测试在给定时间后停止:

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

How can this be done in JUnit 5?这如何在 JUnit 5 中完成?

Closely related to (and code taken from) timeout parameter for Annotation Type Test , but for JUnit 5.Annotation Type Test 的超时参数(和代码取自)密切相关,但对于 JUnit 5。

The strict equivalent of the timeout attribute is the declarative @Timeout annotation. timeout属性的严格等价物是声明性的@Timeout注释。
From the JUnit 5 documentation : 从 JUnit 5 文档

The @Timeout annotation allows one to declare that a test, test factory, test template, or lifecycle method should fail if its execution time exceeds a given duration. @Timeout注释允许人们声明如果测试、测试工厂、测试模板或生命周期方法的执行时间超过给定的持续时间,它应该失败。 The time unit for the duration defaults to seconds but is configurable.持续时间的时间单位默认为秒,但可配置。

For example :例如 :

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

Assertions.assertTimeout() and Assertions.assertTimeoutPreemptively() are new concepts introduced in JUnit 5 (not existing in JUnit 4). Assertions.assertTimeout()Assertions.assertTimeoutPreemptively()是 JUnit 5 中引入的新概念(JUnit 4 中不存在)。 These are alternatives to @Timeout that narrow the timeout to a specific set of statements : these defined in the Executable or in the Supplier passed as parameter.这些是@Timeout的替代方案,可将超时缩小到一组特定的语句:这些语句在Executable或作为参数传递的Supplier中定义。
These two methods (with a very close name) address the same overall goal but with a subtle difference.这两种方法(名称非常接近)解决了相同的总体目标,但存在细微差别。
assertTimeoutPreemptively() preemptively aborts the Executable/Supplier if the timeout occurs while assertTimeout() does not.如果发生超时而assertTimeout()没有发生超时,assertTimeoutPreemptively( assertTimeoutPreemptively()会抢先中止Executable/Supplier
To achieve it, assertTimeoutPreemptively() executes the provided Executable/Supplier in a different thread than that of the calling code while assertTimeout() executes it in the same thread.为了实现它, assertTimeoutPreemptively()在与调用代码不同的线程中执行提供的Executable/Supplier ,而assertTimeout()在同一个线程中执行它。

Warning from the official documentation : Code/libraries relying on the java.lang.ThreadLocal storage for the test execution setup/teardown may have undesirable side effects with assertTimeoutPreemptively() since that executes the provided statements in a different thread.来自官方文档的警告:依赖于java.lang.ThreadLocal存储进行测试执行设置/拆卸的代码/库可能会对assertTimeoutPreemptively()产生不良副作用,因为它会在不同的线程中执行提供的语句。

Use the assertTimeoutPreemptively static assertion from org.junit.jupiter.api.Assertions :使用来自org.junit.jupiter.api.AssertionsassertTimeoutPreemptively静态断言:

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

In addition to the other answers which specify a timeout for a specific test (per the OP request), beginning in JUnit 5.5 it is also possible to configure a global timeout, a useful option instead of adding the @Timeout annotation to every method.除了为特定测试(根据 OP 请求)指定超时的其他答案之外,从 JUnit 5.5 开始,还可以配置全局超时,这是一个有用的选项,而不是为每个方法添加@Timeout注释。

Per the JUnit 5 User Guide , which documents the syntax in the other answers:根据JUnit 5 User Guide ,其中记录了其他答案中的语法:

configuration parameters can be used to specify global timeouts for all methods of a certain category unless they or an enclosing test class is annotated with @Timeout配置参数可用于为某个类别的所有方法指定全局超时,除非它们或封闭的测试类使用 @Timeout 注释

For example, this would set a global timeout of 500 milliseconds for all testable and lifecycle methods:例如,这将为所有可测试和生命周期方法设置 500 毫秒的全局超时:

junit.jupiter.execution.timeout.default = 500 ms

The timeouts can be more narrowly scoped, for example just @Test methods:超时的范围可以更窄,例如只是@Test方法:

junit.jupiter.execution.timeout.testtemplate.method.default = 500 ms

The @Timeout annotation described in the other answers will override these defaults if it is used.如果使用其他答案中描述的@Timeout注释,它将覆盖这些默认值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM