Hakanai
Hakanai

Reputation: 12670

Is there a way to get a callback from JUnit5 if a test is timed out?

In JUnit 4, we used to have to use a Timeout rule which we would explicitly put on a test if we wanted it to time out. (In reality we ended up putting this on the base class for all tests, because we always want tests to time out.)

This led to us eventually customising the Timeout rule such that before it interrupted the test, it recorded its stack trace.

In JUnit 5, timeouts are now always active (hooray), but I'm thinking about how we would add in recording of the stack trace before the test is timed out.

Is there some kind of intercept point or extension which is called before the test is timed out, which we could hook in at to record additional information?

Upvotes: 1

Views: 402

Answers (1)

Sam Brannen
Sam Brannen

Reputation: 31177

I don't think there is any way to do something immediately before the test is timed out, but you can implement a TestExecutionExceptionHandler that checks for a TimeoutException and do something with that.

For example, you could analyze/print the suppressed InterruptedException in the TimeoutException as follows.

class TimedOutTests {

    @RegisterExtension
    TestExecutionExceptionHandler timeoutExceptionHandler = (context, throwable) -> {
        if (throwable instanceof TimeoutException && throwable.getSuppressed().length > 0
                && throwable.getSuppressed()[0] instanceof InterruptedException) {
            throwable.getSuppressed()[0].printStackTrace(System.out);
        }
        throw throwable;
    };

    @Test
    @Timeout(value = 100, unit = MILLISECONDS)
    void takesTooLong() throws Exception {
        Thread.sleep(500);
    }

}

For further details, feel free to consult the implementation of org.junit.jupiter.engine.extension.TimeoutInvocation.

Upvotes: 3

Related Questions