Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding more information when JUnit 4 timeouts with parameterized runner

I am running a JUnit 4 test using @RunWith(value = Parameterized.class). This works fine, no problems there. However, when any of my 34 tests timeout, I only get the message java.lang.Exception: test timed out after 15000 milliseconds. I want it to also show the parameter of the test.

I have even tried to do it like the code below (which I know is a horrible solution for most cases, I just wanted to see if I could get the message to show any time at all), but that did not work, it still resulted in the message above.

private String parameter;

@Test(timeout = 15000)
public void solveAll() {
    try {
        // ... do something that might take a long time
    }
    catch (Throwable e) {
        Assert.fail(this.parameter + " failed! Because of " + e.getMessage());
    }
}

How can I make JUnit also show this.parameter when the test results in a timeout ?

Here is a very simple example test class that shows this problem:

public class ShowMyMessageTest {
    @Test(timeout=1000)
    public void test() {
        try {
            Thread.sleep(3000);
        }
        catch (Throwable e) {
            Assert.fail("Timeout reached with value 42");
        }
    }
}

With this ShowMyMessageTest I sometimes get the expected "Timeout reached with value 42", and sometimes I get only "java.lang.Exception: test timed out after 1000 milliseconds". I want to always get "Timeout reached with value 42" in this case.

like image 866
Simon Forsberg Avatar asked Dec 23 '12 18:12

Simon Forsberg


People also ask

How do you add a timeout in JUnit?

JUnit provides a handy option of Timeout. If a test case takes more time than the specified number of milliseconds, then JUnit will automatically mark it as failed. The timeout parameter is used along with @Test annotation. Let us see the @Test(timeout) in action.

Which is the correct way for simulating timeout in JUnit?

Timeout Example mkyong; import org. junit. Test; public class TimeoutTest { //This test will always failed :) @Test(timeout = 1000) public void infinity() { while (true) ; } //This test can't run more than 5 seconds, else failed @Test(timeout = 5000) public void testSlowMethod() { //... } }

What is difference between junit4 and junit5?

Differences Between JUnit 4 and JUnit 5 Some other differences include: The minimum JDK for JUnit 4 was JDK 5, while JUnit 5 requires at least JDK 8. The @Before , @BeforeClass , @After , and @AfterClass annotations are now the more readable as the @BeforeEach , @BeforeAll , @AfterEach , and @AfterAll annotations.

What does @test timeout 1000 annotation does in JUnit framework?

Annotations for Junit testing @Test(timeout=1000) annotation specifies that method will be failed if it takes longer than 1000 milliseconds (1 second).


1 Answers

This is a bit of a hack, but you could use @After to check the state of the parameter:

@RunWith(Parameterized.class) public class FooTest {
  private boolean flag = true;
  private String param;

  public FooTest(String param) {
    this.param = param;
  }

  @Test(timeout = 1000) public void test() {
    while(true == flag);
    param = null;
  }

  @After public void after() {
    Assert.assertNull("Problem:" + param, param);
  }

  @Parameters public static Collection<Object[]> params() {
    Object[][] params = { { "foo" } };
    return Arrays.asList(params);
  }
}

An alternative is to write your own runner.

like image 173
McDowell Avatar answered Sep 22 '22 13:09

McDowell