JUnit 4 Timeout for Tests Example

1. Overview

In this example, We will learn if a test is taking longer than a defined “timeout” to finish, a TestTimedOutException will be thrown and the test marked failed.
Tests that 'runaway' or take too long, can be automatically failed. There are two options for implementing this behavior:
  • Timeout parameter on @Test Annotation (applies to test method)
  • Global Timeout Management with JUnit Foundation

2. Timeout parameter on @Test Annotation (applies to test method)

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() {
  ...
}
This is implemented by running the test method in a separate thread. If the test runs longer than the allotted timeout, the test will fail and JUnit will interrupt the thread running the test. If test times out while executing an interruptible operation, the thread running the test will exit (if the test is in an infinite loop, the thread running the test will run forever, while other tests continue to execute).

Timeout Rule (applies to all test cases in the test class)

The Timeout Rule applies the same timeout to all test methods in a class, and will execute in addition to any timeout specified by the timeout parameter on an individual Test annotation.:
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Timeout;

public class HasGlobalTimeout {
    public static String log;
    private final CountDownLatch latch = new CountDownLatch(1);

    @Rule
    public Timeout globalTimeout = Timeout.seconds(10); // 10 seconds max per method tested

    @Test
    public void testSleepForTooLong() throws Exception {
        log += "ran1";
        TimeUnit.SECONDS.sleep(100); // sleep for 100 seconds
    }

    @Test
    public void testBlockForever() throws Exception {
        log += "ran2";
        latch.await(); // will block 
    }
}
The timeout specified in the Timeout rule applies to the entire test fixture, including any @Beforeor @After methods. If the test method is in an infinite loop (or is otherwise not responsive to interrupts) then @After methods will not be called.

3. Global Timeout Management with JUnit Foundation

This example shows you how to create a global timeout rule, this rule will apply to all the test methods in a class.
Timeout management is applied by HookInstallingRunner, activated by setting the TEST_TIMEOUTconfiguration option to the desired default test timeout interval in milliseconds. This timeout specification is applied to every test method that doesn't explicitly specify a longer interval.
import org.junit.runner.RunWith;
import com.nordstrom.automation.junit.HookInstallingRunner;

@RunWith(HookInstallingRunner.class)
public class ExampleTest {
    
    ...
    
}
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Timeout;

import java.util.concurrent.TimeUnit;

public class TimeoutRuleTest {

    //global timeout rule
    @Rule
    public Timeout globalTimeout = Timeout.seconds(1);

 //This test will be failed, because it will take more than 1 second to finish!
    @Test
    public void testSlowMethod1() throws InterruptedException {
        //...
        TimeUnit.SECONDS.sleep(5000);
    }

 //passed
    @Test
    public void testSlowMethod2() {
        //...
    }
}

Comments