JUnit: Multiple Runners and Dependent Tests

There are times that you may want to run a test case with multiple @RunWith annotations or you may have a bootstrap test class that you must run before every other test, such as bootstrapping the application during integration testing. JUnit by its nature does not have test class chaining but there is an easy solution.

In this example I will mention SpringJUnit4ClassRunner which is used to bootstrap a Spring context, which is handy for integration testing, but this method applies to every case for JUnit, not just Spring. We also use CasperRunner to run CasperJS tests. However, CasperJS tests must run after the context has been initialized, and this order is not deterministic in JUnit.

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
@WebIntegrationTest
public class MainTest {

  @Test
  public void subRunner() throws Exception {
    System.out.println("MainTest subRunner()");
    JUnitCore.runClasses(SubTestWithRunner.class);
  }

  @RunWith(CasperRunner.class)
  public static class SubTestWithRunner {
    @BeforeClass
    public static void init() throws Exception {
      System.out.println("SubTestWithRunner init()");
    }
  }
}

MainTest will be runned by JUnit. SubTestWithRunner depends on it (by logic) and it will be runned inside of the main in a @Test method, during the call JUnitCore.runClasses(SubTestWithRunner.class). This method ensures the main runner is started correctly before sub runner runs, effectively implementing multiple nested @RunWith annotations with dependent test classes.