Open In App

JUnit 5 – @Timeout

The @Timeout annotation in JUnit restricts the duration of test and lifecycle methods. It aids in ensuring that a test procedure is completed according to the planned timetable. TimeoutExceptions occur when the duration of the test method exceeds the specified limit.

Any JUnit test or lifecycle method can utilize @Timeout. Add the @Timeout annotation to the class declaration to set a global timeout for all tests. To override the global timeout, apply the @Timeout annotation to a specific test method.



There are a few circumstances when using JUnit’s @Timeout annotation might be beneficial:

Implementation of @Timeout in JUnit 5

We’ll see some methods for implementing the @Timeout annotation in JUnit using Eclipse. If you don’t have Eclipse, ensure you have a platform that supports writing and executing JUnit tests. We’ll demonstrate how to use @Timeout to test methods implemented within your project, providing a reference for crafting tests for your existing methods.

Within Eclipse IDE, these are the initial steps:



Step 1: Create a Java project.

Step 2: Under the src folder, create a package named timeoutTest.

Note: This is a sample structure for implementing JUnit’s @Timeout feature. Your actual project environment may differ.

Now, we’ll shift our focus to the timeOutTest.java class to write tests and observe the behavior of @Timeout in various scenarios.

Section 1: Using Timeout() annotation

Test 1: Demonstrates using Timeout annotation with Thread.sleep

Checks if a method finishes within 6 seconds using Thread.sleep to delay for 5 seconds. It should pass.




// Test 1: Demonstrates using Timeout annotation with Thread.sleep
@Test
@Timeout(6) // Set timeout to 6 seconds
public void test1() throws InterruptedException {
    Thread.sleep(5000); // Simulate a 5-second delay
    System.out.println("Test1 Passed within the time");
}

Test 2: Demonstrates using Timeout annotation with TimeUnit.SECONDS.sleep

Same as Test 1 but employs TimeUnit.SECONDS.sleep to imitate the delay. It should also pass.




// Test 2: Demonstrates using Timeout annotation with TimeUnit.SECONDS.sleep
@Test
@Timeout(6) // Set timeout to 6 seconds
public void test2() throws InterruptedException {
    TimeUnit.SECONDS.sleep(5); // Another way to simulate a 5-second delay
    System.out.println("Test2 Passed within the time");
}

Section 2: Using Assertions

Test 3: Demonstrates using Assertions.assertTimeout

Uses Assertions.assertTimeout to confirm a procedure completes inside 7 seconds. It mimics a 6-second delay using a helper method and should pass.




// Test 3: Demonstrates using Assertions.assertTimeout
@Test
public void test3() {
    Assertions.assertTimeout(Duration.ofSeconds(7), () -> delaySeconds(6)); 
      // Assert a timeout of 7 seconds for a
    // 6-second delay
      
      System.out.println("Test3 Passed within the time");
}
  
// Helper method to simulate delays
private void delaySeconds(int seconds) throws InterruptedException {
    TimeUnit.SECONDS.sleep(seconds);
}

Section 3: Demonstrating timeout failures

Test 4: Using Assertions.assertTimeout to handle timeout failure.

Expects a timeout failure since it asserts a 4-second timeout but delays for 5 seconds using Thread.sleep.




// Test 4: Using Assertions.assertTimeout to handle timeout failure
@Test
public void test4() {
    Assertions.assertTimeout(Duration.ofSeconds(4), () -> {
        try {
            Thread.sleep(5000); // Delay of 5 seconds, expected to fail
        } catch (InterruptedException e) {
            // Handle interruption if needed
        }
    });
}

Test 5: Same as Test 4, using TimeUnit.SECONDS.sleep

Similar to Test 4 but utilizes TimeUnit.SECONDS.sleep for the delay. It should also fail.




//Test 5: Same as Test 4, using TimeUnit.SECONDS.sleep
@Test
public void test5() {
    Assertions.assertTimeout(Duration.ofSeconds(4), () -> {
        try {
            TimeUnit.SECONDS.sleep(5); // Delay of 5 seconds, expected to fail
        } catch (InterruptedException e) {
            // Handle interruption if needed
        }
    });
}

Test 6: Using Assertions.assertTimeout with a shorter timeout than delay

Another expected timeout failure, asserting a 5-second timeout for a 6-second delay using a helper function.




// Test 6: Using Assertions.assertTimeout with a shorter
// timeout than delay
@Test public void test6()
{
    // Assert a timeout of 5 seconds for a
    // 6-second delay
    Assertions.assertTimeout(Duration.ofSeconds(5),() -> delaySeconds1(6));
}
  
// Helper method for Test 6
private void delaySeconds1(int seconds) throws InterruptedException
{
    TimeUnit.SECONDS.sleep(seconds);
}

Final timeOutText.java will be :




package timeoutTest;
  
// This package contains tests for timeout functionality.
import java.time.Duration; // Import for handling time durations.
import java.util.concurrent.TimeUnit; // Import for time-related utility classes.
import org.junit.jupiter.api.Assertions; // Import for JUnit assertions.
import org.junit.jupiter.api.Test; // Import for JUnit test annotations.
import org.junit.jupiter.api.Timeout; // Import for setting test timeouts.
  
// This class demonstrates different ways to apply timeouts in JUnit tests.
class TimeOutTest {
  
// Section 1: Using Timeout() annotation
  
    // Test 1: Demonstrates using Timeout annotation with Thread.sleep
    @Test
    @Timeout(6) // Set timeout to 6 seconds
    public void test1() throws InterruptedException {
        Thread.sleep(5000); // Simulate a 5-second delay
        System.out.println("Test1 Passed within the time");
    }
  
    // Test 2: Demonstrates using Timeout annotation with TimeUnit.SECONDS.sleep
    @Test
    @Timeout(6) // Set timeout to 6 seconds
    public void test2() throws InterruptedException {
        TimeUnit.SECONDS.sleep(5); // Another way to simulate a 5-second delay
        System.out.println("Test2 Passed within the time");
    }
  
// Section 2: Using Assertions
  
    // Test 3: Demonstrates using Assertions.assertTimeout
    @Test
    public void test3() {
        Assertions.assertTimeout(Duration.ofSeconds(7), () -> delaySeconds(6)); // Assert a timeout of 7 seconds for a
                                                                                // 6-second delay
        System.out.println("Test3 Passed within the time");
    }
  
    // Helper method to simulate delays
    private void delaySeconds(int seconds) throws InterruptedException {
        TimeUnit.SECONDS.sleep(seconds);
    }
  
// Section 3: Demonstrating timeout failures
  
    //Test 4: Using Assertions.assertTimeout to handle timeout failure
    @Test
    public void test4() {
        Assertions.assertTimeout(Duration.ofSeconds(4), () -> {
            try {
                Thread.sleep(5000); // Delay of 5 seconds, expected to fail
            } catch (InterruptedException e) {
                // Handle interruption if needed
            }
        });
    }
  
    //Test 5: Same as Test 4, using TimeUnit.SECONDS.sleep
    @Test
    public void test5() {
        Assertions.assertTimeout(Duration.ofSeconds(4), () -> {
            try {
                TimeUnit.SECONDS.sleep(5); // Delay of 5 seconds, expected to fail
            } catch (InterruptedException e) {
                // Handle interruption if needed
            }
        });
    }
  
    // Test 6: Using Assertions.assertTimeout with a shorter timeout than delay
    @Test
    public void test6() {
        Assertions.assertTimeout(Duration.ofSeconds(5), () -> delaySeconds1(6)); 
          // Assert a timeout of 5 seconds for a 6-second delay
    }
  
    // Helper method for Test 6
    private void delaySeconds1(int seconds) throws InterruptedException {
        TimeUnit.SECONDS.sleep(seconds);
    }
}

Video Demo Execution

Let’s see how the execution of all six written tests happens in this article:

FAQs pertaining to JUnit’s @Timeout annotation

1. What is the @Timeout annotation’s primary function?

It acts as a safety precaution to keep testing from going too long. It’s similar to giving your tests a time limit and making sure they finish within that window.

2. What is the proper way to use @Timeout in my tests?

It’s really very easy! You have two options:

  • Include it in several test techniques: This creates a timeout just for that particular test.
  • Use it throughout the entirety of the test class: This includes an additional global timeout for every test in that class.

3. What occurs when an exam goes beyond the allotted time?

TimeoutException will be raised, informing you that the operation took too long to finish.

4. When is the best time to use @Timeout?

It’s especially useful in situations like:

  • Slow network calls
  • Extended testing
  • Possible impasses
  • Endless loops

Article Tags :