Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Simple JUnit rule to make tests retry
public class RetrierTest {
private static int count = 0;
@Rule public RetryRule rule = new RetryRule();
@Test
@Retry
public void failsFirst() throws Exception {
count++;
assertEquals(2, count);
}
}
@Retention(RetentionPolicy.RUNTIME)
public @interface Retry {}
public class RetryRule implements MethodRule {
@Override public Statement apply(final Statement base, final FrameworkMethod method, Object target) {
return new Statement() {
@Override public void evaluate() throws Throwable {
try {
base.evaluate();
} catch (Throwable t) {
Retry retry = method.getAnnotation(Retry.class);
if (retry != null) {
base.evaluate();
} else {
throw t;
}
}
}
};
}
}
@ashokdaukiya
Copy link

ashokdaukiya commented Jul 9, 2019

not working for me test get failed but it will not retry
error androidTest.RetryRule$1.evaluate(RetryRule.java:16)
junit.framework.AssertionFailedError: expected:<5> but was:<2>

@tomdwp
Copy link

tomdwp commented Mar 16, 2021

@AndreSand is there a way to adapt your snippet to work on a per-test basis? (instead of a per-test-class basis)

@a-oleynik
Copy link

a-oleynik commented Jul 18, 2021

@tomdwp
public class RetryRule implements MethodRule {

private AtomicInteger retryCount;

public RetryRule() {
    this(3);
}

public RetryRule(int retries) {
    super();
    this.retryCount = new AtomicInteger(retries);
}

@Override
public Statement apply(final Statement base, final FrameworkMethod method, Object target) {
    return new Statement() {
        @Override
        public void evaluate() throws Throwable {
            Throwable caughtThrowable = null;

            while (retryCount.getAndDecrement() > 0) {
                try {
                    base.evaluate();
                    return;
                } catch (Throwable t) {
                    if (retryCount.get() > 0 &&
                            method.getAnnotation(Retry.class) != null) {
                        caughtThrowable = t;
                        System.err.println(
                                method.getName() +
                                        ": Failed, " +
                                        retryCount.toString() +
                                        "retries remain");
                    } else {
                        throw caughtThrowable;
                    }
                }
            }
        }
    };
}

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment