Vous pouvez le faire avec un TestRule. Cela vous donnera la souplesse dont vous avez besoin. Un TestRule vous permet d'insérer de la logique de l'essai, de sorte que vous pouvez implémenter la boucle de nouvelle tentative:
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");
}
}
Le cœur d'un TestRule
est le base.evaluate()
, qui appelle la méthode de test. Donc autour de cet appel vous mettre une boucle de nouvelle tentative. Si une exception est levée dans votre méthode de test (un échec d'assertion est en fait un AssertionError
), alors le test a échoué, et vous devrez recommencer.
Il y a une autre chose qui peut être utile. Vous ne voulez appliquer cette logique de nouvelle tentative à une série de tests, dans ce cas, vous pouvez ajouter dans la nouvelle tentative de la classe au-dessus d'un test pour une annotation sur la méthode. Description
contient une liste d'annotations pour la méthode. Pour plus d'informations à ce sujet, voir ma réponse à la Façon d'exécuter du code avant chaque JUnit @la méthode d'Essai individuellement, sans utiliser l'annotation @RunWith ni AOP?.
À l'aide d'un Lanceur personnalisé
C'est la suggestion de CKuck, vous pouvez définir votre propre Coureur. Vous avez besoin d'étendre BlockJUnit4ClassRunner et remplacer runChild(). Pour plus d'informations, voir ma réponse à Comment définir JUnit méthode de la règle dans une suite?. Cette réponse explique comment définir la façon d'exécuter le code pour chaque méthode dans une Suite, pour laquelle vous devez définir votre propre Coureur.