Search code examples
javareflectionjunitannotationstest-suite

Do JUnit test suites support custom annotations?


In JUnit, you can create test suites like so:

public class SecurityTest1 {
    @Test
    public void testSecurity1() {
        // ...
    }
}

public class LoadTest1 {
    @Test
    public void testLoad1() {
        // ...
    }
}

public class SecurityTest2 {
    @Test
    public void testSecurity2() {
        // ...
    }
}

@RunWith(Suite.class)
@SuiteClasses({SecurityTest1.class, SecurityTest2.class})
public class SecurityTestSuite {}

But this seems rather cumbersome. It would be so nice to define a simple class-level annotation:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface SecurityTest {} 

And then define your suite like so:

@SecurityTest
public class SecurityTest1 {
    @Test
    public void testSecurity1() {
        // ...
    }
}

public class LoadTest1 {
    @Test
    public void testLoad1() {
        // ...
    }
}

@SecurityTest
public class SecurityTest2 {
    @Test
    public void testSecurity2() {
        // ...
    }
}

@RunWith(Suite.class)
@SuiteClasses({SecurityTest.class})
public class SecurityTestSuite {}

Is this possible? If so how? Note: not interested in switching to TestNG or any other test framework if JUnit does not support this...thanks in advance!


Solution

  • You can do it by implementing your own Test Runner similar to the Suite runner.

    This runner should extract the marker annotation class from the value of the @SuiteClasses annotation (you should probably replace @SuiteClasses with your own annotation). Take a look at the getAnnotatedClasses method of the org.junit.runners.Suite class.
    After having the marker annotation class, you should scan the classpath for test classes marked with this annotation (use a library such as Reflections) and pass an array of them to the appropriate Runner constructor.
    You can find a similar behavior in the Suite constructor:

    public Suite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
       this(builder, klass, getAnnotatedClasses(klass));
    }