Using @Test(timeout = 15) not thread-safe, using it can lead to an incorrect result. Use the following code.
public class Test { @Rule public Timeout globalTimeout= new Timeout(9); @org.junit.Test() public void test() throws InterruptedException { Thread.sleep(8); } @org.junit.Test() public void test2() throws InterruptedException { Thread.sleep(10); } }
conclusion
org.junit.runners.model.TestTimedOutException: test timed out after 9 milliseconds at java.lang.Thread.sleep(Native Method) at Test.test2(Test.java:22) 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:497) 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.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)
This approach allows you to catch even 1 millisecond.
Also in jUnit5 you can use
assertTimeoutPreemptively(ofSeconds(15), () -> { // This method takes 20 seconds to run myMethod(); } , () -> "myMethod() method took more than 15 seconds and was aborted.");