Skip to content

Instantly share code, notes, and snippets.

@trobalik
Created June 2, 2016 21:49
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save trobalik/b812e2a4d36edcf4157c279b143c8de1 to your computer and use it in GitHub Desktop.
Save trobalik/b812e2a4d36edcf4157c279b143c8de1 to your computer and use it in GitHub Desktop.
Flaky Espresso Tests and the RetryTestRule
package com.yourapp.test;
// import statements...
public class FlakyTests {
@Rule
RetryTestRule retry = new RetryTestRule(3); // will attempt each test up to 3 times
@Test
public void testSomethingUpToThreeTimes() throw Exception {
// test stuff
}
}
package com.yourapp.test;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
/**
* A JUnit {@link TestRule} that implements logic to try a test any number of times before giving up and allowing it to fail.
*/
public class RetryTestRule implements TestRule {
private static final String TAG = RetryTestRule.class.getSimpleName();
private final int mRetryCount;
public RetryTestRule(int retryCount) {
mRetryCount = retryCount;
}
@Override
public Statement apply(Statement base, Description description) {
return new RetryStatement(base, description, mRetryCount);
}
private static class RetryStatement extends Statement {
private final Statement mBase;
private final Description mDescription;
private final int mRetryCount;
private RetryStatement(Statement base, Description description, int retryCount) {
mBase = base;
mDescription = description;
mRetryCount = retryCount;
}
@Override
public void evaluate() throws Throwable {
Throwable testError = null;
int numFails = 0;
for (int i = 0; i < mRetryCount; i++) {
try {
mBase.evaluate();
Log.d(TAG, "Out of %d runs, %d failed", i + 1, numFails);
return;
} catch (Throwable t) {
Log.e(TAG, "%s: run %d failed", mDescription.getDisplayName(), i + 1);
testError = t;
numFails++;
}
}
Log.e(TAG, "%s: giving up after %d failures", mDescription.getDisplayName(), mRetryCount);
throw testError;
}
}
}
@christopherperry
Copy link

This makes me incredibly nervous. What's the underlying bug in the framework that is prompting this hack?

@sfoley-gpqa
Copy link

I like this and am using it but I'm getting a "java.lang.RuntimeException: Could not launch intent Intent" error. It looks like, when the flaky test fails, the activity I was using isn't being stopped/removed.

I tried calling myActivityRule.getActivity().finish() in my @after method but the activity still isn't being stopped.

I'm new to Espresso and TestRules. Would appreciate some advice :)

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