Puede hacer esto con TestRule . Esto le dará la flexibilidad que necesita. Una TestRule le permite insertar lógica alrededor de la prueba, por lo que implementaría el ciclo de reintento:
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;
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");
}
}
El corazón de a TestRule
es el base.evaluate()
, que llama a su método de prueba. Entonces, alrededor de esta llamada, pones un bucle de reintento. Si se lanza una excepción en su método de prueba (un error de aserción es en realidad un AssertionError
), entonces la prueba ha fallado y volverá a intentarlo.
Hay otra cosa que puede ser útil. Es posible que solo desee aplicar esta lógica de reintento a un conjunto de pruebas, en cuyo caso puede agregar a la clase Reintentar encima de una prueba para una anotación particular en el método. Description
contiene una lista de anotaciones para el método. Para obtener más información sobre esto, consulte mi respuesta a ¿Cómo ejecutar un código antes de cada método JUnit @Test individualmente, sin usar @RunWith ni AOP? .
Usando un TestRunner personalizado
Esta es la sugerencia de CKuck, puedes definir tu propio Runner. Necesita extender BlockJUnit4ClassRunner y anular runChild (). Para obtener más información, consulte mi respuesta a ¿Cómo definir la regla del método JUnit en una suite? . Esta respuesta detalla cómo definir cómo ejecutar código para cada método en una Suite, para lo cual debe definir su propio Runner.