Вы можете сделать это с помощью TestRule . Это даст вам необходимую гибкость. TestRule позволяет вам вставить логику вокруг теста, чтобы вы могли реализовать цикл повторных попыток:
public class RetryTest {
public class Retry implements TestRule {
private int retryCount;
public Retry(int retryCount) {
this.retryCount = retryCount;
}
public Statement apply(Statement base, Description description) {
return statement(base, description);
}
private Statement statement(final Statement base, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
Throwable caughtThrowable = null;
// implement retry logic here
for (int i = 0; i < retryCount; i++) {
try {
base.evaluate();
return;
} catch (Throwable t) {
caughtThrowable = t;
System.err.println(description.getDisplayName() + ": run " + (i+1) + " failed");
}
}
System.err.println(description.getDisplayName() + ": giving up after " + retryCount + " failures");
throw caughtThrowable;
}
};
}
}
@Rule
public Retry retry = new Retry(3);
@Test
public void test1() {
}
@Test
public void test2() {
Object o = null;
o.equals("foo");
}
}
Сердцем TestRule
является base.evaluate()
, который вызывает ваш метод тестирования. Так что вокруг этого звонка вы положили повторную петлю. Если в вашем методе тестирования возникнет исключение (на самом деле ошибка подтверждения AssertionError
), то проверка не пройдена, и вы повторите попытку.
Есть еще одна вещь, которая может быть полезной. Возможно, вы захотите применить эту логику повторения только к набору тестов, и в этом случае вы можете добавить в класс Retry выше тест для конкретной аннотации метода. Description
содержит список аннотаций для метода. Для получения дополнительной информации об этом см. Мой ответ на Как запускать некоторый код перед каждым методом JUnit @Test отдельно, без использования @RunWith или AOP? .
Использование пользовательского TestRunner
Это предложение CKuck, вы можете определить свой собственный Runner. Вам необходимо расширить BlockJUnit4ClassRunner и переопределить runChild (). Для получения дополнительной информации см. Мой ответ на Как определить правило метода JUnit в комплекте? . В этом ответе подробно описано, как определить, как запускать код для каждого метода в Suite, для которого вам нужно определить свой собственный Runner.