Using TestRule
one can alter the behavior of a test method. In this article, we will see an example of JUnit’s Timeout rule that makes sure that each test is run in a time limit manner. Timeout rule is applied to all test methods where each test is run in a separate thread in a time bound manner. If the test didn’t finish within the specified time, a TestTimedOutException
will be thrown.
Internally the statement that executes the test is wrapped around the another statement that in turn runs the the original statement in a separate thread and waits for the result using the specified timeout value.
Below is a test class that runs the test aTestHanging
, will automatically fail after waiting for 5 secs. We define the timeout rule using a non-static, public instance variable of type Timeout
. A timeout instance is created using the factory method Timeout.millis()
where we pass the timeout in mill seconds.
TimeoutExample:
package com.javarticles.junit; import org.junit.After; import org.junit.AfterClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.Timeout; public class TimeoutExample { @Rule public final Timeout timeOut = Timeout.millis(5000); @Test public void aTestHanging() { System.out.println("Start test"); for(;;){} } @After public void afterTest() { System.out.println("After test - wont be called due to timeout"); } @AfterClass public static void done() { System.out.println("Test finished due to timeout"); } }
As you can see the test doesn’t finish so the @After
test method is not run.
Output:
Befor class Before test Start test After class
Test fails with timeout exception.
Error Trace:
org.junit.runners.model.TestTimedOutException: test timed out after 5000 milliseconds at com.javarticles.junit.TimeoutExample.aTestHanging(TimeoutExample.java:18) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:298) at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:292) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.lang.Thread.run(Thread.java:745)
Download the source code
This was an example about JUnit Timeout TestRule.