Ответ 1
Это можно сделать, но для этого нужна небольшая работа. Вам также нужно определить свой собственный бегун Suite и собственный тестовый бегун, а затем переопределить runChild() в тестовом бегуне. Использование следующих классов Suite и Test:
@RunWith(MySuite.class)
@SuiteClasses({Class1Test.class})
public class AllTests {
}
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
на методе и делаем что-то, если оно есть. Остальное остается упражнением для читателя. Когда я запускаю вышеупомянутый Suite, я получаю вывод:
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
Обратите внимание, что Suite имеет несколько конструкторов в зависимости от того, как он вызывается. Вышеупомянутое работает с Eclipse, но я не тестировал другие способы запуска Suite. См. Комментарии рядом с различными конструкторами для Suite для получения дополнительной информации.