Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

junit

junit5

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.

like image 389
A Jar of Clay Avatar asked Jul 19 '19 17:07

A Jar of Clay


People also ask

How will you set the timeout in test cases in JUnit?

JUnit provides a handy option of Timeout. If a test case takes more time than the specified number of milliseconds, then JUnit will automatically mark it as failed. The timeout parameter is used along with @Test annotation. Let us see the @Test(timeout) in action.

Which is the correct way for simulating timeout of 1000 in JUnit?

Timeout Example mkyong; import org. junit. Test; public class TimeoutTest { //This test will always failed :) @Test(timeout = 1000) public void infinity() { while (true) ; } //This test can't run more than 5 seconds, else failed @Test(timeout = 5000) public void testSlowMethod() { //... } }

How does the parameter timeout in @test timeout 100 work?

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.

What does @test timeout 1000 annotation does in JUnit framework?

You can optionally specify a timeout in milliseconds to cause a test method to fail if it takes longer than that number of milliseconds. If the time limit is exceeded, then the failure is triggered by an Exception being thrown: @Test(timeout=1000) public void testWithTimeout() { ... }


1 Answers

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.

like image 159
davidxxx Avatar answered Sep 29 '22 16:09

davidxxx