Reputation: 6318
In JUnit 4 the "timeout" annotation parameter can be used to force a test to stop after the given amount of time:
@Test(timeout=100)
public void infinity() {
while(true);
}
How can this be done in JUnit 5?
Closely related to (and code taken from) timeout parameter for Annotation Type Test, but for JUnit 5.
Upvotes: 26
Views: 22627
Reputation: 9140
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.
Per the JUnit 5 User Guide, which documents the syntax in the other answers:
configuration parameters can be used to specify default timeouts for all methods of a certain category unless they or an enclosing test class is annotated with
@Timeout
For example, this would set a global timeout of 500 milliseconds for all testable and lifecycle methods:
junit.jupiter.execution.timeout.default = 500 ms
The timeouts can be more narrowly scoped, for example just @Test
methods:
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.
Upvotes: 5
Reputation: 131546
The strict equivalent of the timeout
attribute is the declarative @Timeout
annotation.
From the JUnit 5 documentation :
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. 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).
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.
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.
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.
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.
Upvotes: 40
Reputation: 6318
Use the assertTimeoutPreemptively
static assertion from org.junit.jupiter.api.Assertions
:
@Test
public void infinity() {
assertTimeoutPreemptively(Duration.ofMillis(100), () -> {
while (true);
});
}
Upvotes: 11