Search code examples
javaantjunittimeoutjunit4

What's the best way to set up a per-test or per-class timeout when using <junit> in perBatch forkmode?


I want to fail the build if anyone writes a test that takes longer than 1 second to run, but if I run in perTest mode it takes much, much longer.

I could probably write a custom task that parses the junit reports and fails the build based on that, but I was wondering if anyone knows or can think of a better option.


Solution

  • Reviving an old question since the answer doesn't provide an example.

    You can specify timeout

    1. Per test method:

       @Test(timeout = 100) // Exception: test timed out after 100 milliseconds
       public void test1() throws Exception {
           Thread.sleep(200);
       }
      
    2. For all methods in a test class using Timeout @Rule:

       @Rule
       public Timeout timeout = new Timeout(100);
      
       @Test // Exception: test timed out after 100 milliseconds
       public void methodTimeout() throws Exception {
           Thread.sleep(200);
       }
      
       @Test
       public void methodInTime() throws Exception {
           Thread.sleep(50);
       }
      
    3. Globally for the total time to run all test methods in the class using a static Timeout @ClassRule:

       @ClassRule
       public static Timeout classTimeout = new Timeout(200);
      
       @Test
       public void test1() throws Exception {
           Thread.sleep(150);
       }
      
       @Test // InterruptedException: sleep interrupted
       public void test2() throws Exception {
           Thread.sleep(100);
       }
      
    4. And even apply timeout (either @Rule or @ClassRule) to all classes in your entire suite:

       @RunWith(Suite.class)
       @SuiteClasses({ Test1.class, Test2.class})
       public class SuiteWithTimeout {
           @ClassRule
           public static Timeout classTimeout = new Timeout(1000);
      
           @Rule
           public Timeout timeout = new Timeout(100);
       }
      

    EDIT: timeout was deprecated recently to utilize this initialization

    @Rule
    public Timeout timeout = new Timeout(120000, TimeUnit.MILLISECONDS);
    

    You should provide the Timeunit now, as this will provide more granularity to your code.