这可以做到,但需要一些工作。您还需要定义自己的 Suite runner 和 Test runner,然后在 test runner 中覆盖 runChild()。使用以下内容:
AllTests.java:
@RunWith(MySuite.class)
@SuiteClasses({Class1Test.class})
public class AllTests {
}
Class1Test.java:
public class Class1Test {
@Deprecated @Test public void test1() {
System.out.println("" + this.getClass().getName() + " test1");
}
@Test public void test2() {
System.out.println("" + this.getClass().getName() + " test2");
}
}
请注意,我已将 test1() 注释为 @Deprecated。当您在测试中有 @Deprecated 注释时,您想做一些不同的事情,因此我们需要扩展 Suite 以使用自定义 Runner:
public class MySuite extends Suite {
// copied from Suite
private static Class<?>[] getAnnotatedClasses(Class<?> klass) throws InitializationError {
Suite.SuiteClasses annotation = klass.getAnnotation(Suite.SuiteClasses.class);
if (annotation == null) {
throw new InitializationError(String.format("class '%s' must have a SuiteClasses annotation", klass.getName()));
}
return annotation.value();
}
// copied from Suite
public MySuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
super(null, getRunners(getAnnotatedClasses(klass)));
}
public static List<Runner> getRunners(Class<?>[] classes) throws InitializationError {
List<Runner> runners = new LinkedList<Runner>();
for (Class<?> klazz : classes) {
runners.add(new MyRunner(klazz));
}
return runners;
}
}
JUnit 为它将运行的每个测试创建一个Runner。通常,Suite 只会创建默认的 BlockJUnit4ClassRunner,我们在这里所做的只是覆盖 Suite 的构造函数,该构造函数从 SuiteClass 注释中读取类,并且我们正在使用它们创建自己的运行器 MyRunner。这是我们的 MyRunner 类:
public class MyRunner extends BlockJUnit4ClassRunner {
public MyRunner(Class<?> klass) throws InitializationError {
super(klass);
}
@Override
protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
Description description= describeChild(method);
if (method.getAnnotation(Ignore.class) != null) {
notifier.fireTestIgnored(description);
} else {
if (description.getAnnotation(Deprecated.class) != null) {
System.out.println("name=" + description.getMethodName() + " annotations=" + description.getAnnotations());
}
runLeaf(methodBlock(method), description, notifier);
}
}
}
大部分内容是从BlockJUnit4ClassRunner 复制而来的。我添加的一点是:
if (description.getAnnotation(Deprecated.class) != null) {
System.out.println("name=" + description.getMethodName() + " annotations=" + description.getAnnotations());
}
我们在这里测试方法上是否存在@Deprecated 注释,如果存在则做一些事情。其余的留给读者练习。当我运行上述套件时,我得到输出:
name=test1 annotations=[@java.lang.Deprecated(), @org.junit.Test(expected=class org.junit.Test$None, timeout=0)]
uk.co.farwell.junit.run.Class1Test test1
uk.co.farwell.junit.run.Class1Test test2
请注意,套件有多个构造函数,具体取决于调用方式。以上适用于 Eclipse,但我还没有测试过其他运行套件的方法。有关详细信息,请参阅 cmets 以及 Suite 的各种构造函数。