Elad Benda
Elad Benda

Reputation: 36682

How to define JUnit test time-out at runtime (i.e. without annotations)?

I want to run a unit test with a time-out that is defined at runtime. I want to define a time-out for a specific test only, not the whole class.

I saw these are the ways to set the time out:

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

or

@Test(timeout=100) public void infinity() {
   while(true);
}

but when I run this code, no exception is thrown. I want to identify when the test failed due to timeout.

public Timeout testTimeout;

private void setTestTimeOut() {
    if (!Strings.isNullOrEmpty(testTimeOut)) {
        testTimeout = new Timeout(Integer.parseInt(testTimeOut));
    }
}

How can I catch the exception? Wrap the main method with try-catch(InterruptException)?

Upvotes: 3

Views: 1192

Answers (2)

Cuball
Cuball

Reputation: 89

The @Test(timeout=xxx) will not throw a TimeoutException, it will fail the test.

Could you specify in more detail what you would like to test?

Upvotes: -1

Duncan Jones
Duncan Jones

Reputation: 69410

Add a TestWatcher rule that decides, at run time, whether to apply a timeout or not:

@Rule
public TestWatcher watcher = new TestWatcher() {
  @Override
  public Statement apply(Statement base, Description description) {
    // You can replace this hard-coded test name and delay with something
    // more dynamic
    if (description.getMethodName().equals("infinity")) {
      return new FailOnTimeout(base, 200);
    }

    return base;
  }
};

Your original approach didn't work because JUnit rules take effect before the test code begins to run, so any attempts to adjust your Timeout object within your test are too late.

Upvotes: 3

Related Questions