Created
June 2, 2016 21:49
-
-
Save trobalik/b812e2a4d36edcf4157c279b143c8de1 to your computer and use it in GitHub Desktop.
Flaky Espresso Tests and the RetryTestRule
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} |
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
This makes me incredibly nervous. What's the underlying bug in the framework that is prompting this hack?