tags:

views:

212

answers:

2

I would like to create a junit test suite using JUnit 4 where the names of the test classes to be included are not known until the test suite is run.

In JUnit 3 I could do this:

public final class MasterTester extends TestCase
{
  /**
   * Used by junit to specify what TestCases to run.
   * 
   * @return a suite containing what TestCases to run
   */
  public static TestSuite suite() {
    TestSuite suite = new TestSuite();

    for(Class<?> klass : gatherTestClasses()) {
      suite.addTestSuite(klass);
    }

    return suite;
  }
}

and let the gatherTestClasses() method deal with figuring out what test classes to run.

In JUnit 4, the documentation says to use an annotation: @SuiteClasses({TestClass1.class, TestClass2.class...}) to build up my test suite. There are numerous SO answers showing how to do this. Unfortunately the examples I see do not seem to allow for passing a dynamically generated list of TestClasses.

This SO answer suggested I would have to subclass BlockJUnit4ClassRunner which I do not want to do.

Dynamically specified test suites seem like something that must be in JUnit 4 somewhere. Does anyone know where?

+1  A: 

I'm not sure what gatherTestClasses() does, but let's say it returns some tests when the OS is Linux and different tests when the OS is Windows. You can replicate that in JUnit 4.4 with assumptions:

@Test
public void onlyOnLinux() {
    assumeThat(getOS(), is(OperationSystem.LINUX));
    // rest of test
}

@Test
public void onlyOnWindows() {
    assumeThat(getOS(), is(OperationSystem.WINDOWS));
    // rest of test
}

@Test
public void anyOperatingSystem() {
    // just don't call assumeThat(..)
}

The implementation of getOS() being your custom code.

Brad Cupit
+1  A: 

I found Classpath suite quite useful when used with a naming convention on my test classes.

http://johanneslink.net/projects/cpsuite.jsp

Here is an example:

import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.runner.RunWith;

@RunWith(ClasspathSuite.class)
@ClassnameFilters({".*UnitTest"})
public class MySuite {
}
JavaRocky
Awesome! Thank you!
Tom Tresansky