Skip to content

Instantly share code, notes, and snippets.

@AfzalivE
Last active January 28, 2019 15:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AfzalivE/1e06e13cc2c96edd0f3fec4750356f1d to your computer and use it in GitHub Desktop.
Save AfzalivE/1e06e13cc2c96edd0f3fec4750356f1d to your computer and use it in GitHub Desktop.
Run test if a condition is true
import com.azimolabs.conditionwatcher.Instruction;
import org.junit.Assume;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import timber.log.Timber;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Modifier;
/**
* Cobbled together from:
* https://gist.github.com/designatednerd/153e4545af912aeed1ff
* http://www.codeaffine.com/2013/11/18/a-junit-rule-to-conditionally-ignore-tests/
* https://gist.github.com/yinzara/9980184
* http://cwd.dhemery.com/2010/12/junit-rules/
* http://stackoverflow.com/questions/28145735/androidjunit4-class-org-junit-assume-assumetrue-assumptionviolatedexception/
* <p>
* Works for Android Instrumentation tests
*/
public class ConditionalTestRule implements TestRule {
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface RunIf {
Class<? extends Instruction> condition();
}
@Override
public Statement apply(Statement base, Description description) {
Statement result = base;
if (hasConditionalAnnotation(description)) {
Instruction condition = getRunCondition(description);
result = new RunIfStatement(base, condition);
}
return result;
}
private static boolean hasConditionalAnnotation(Description description) {
return description.getAnnotation(RunIf.class) != null;
}
private static Instruction getRunCondition(Description description) {
RunIf annotation = description.getAnnotation(RunIf.class);
return new RunConditionCreator(description.getTestClass(), annotation).create();
}
private static class RunConditionCreator {
private final Class<?> mTestClass;
private final Class<? extends Instruction> conditionType;
RunConditionCreator(Class<?> atestclass, RunIf annotation) {
this.mTestClass = atestclass;
this.conditionType = annotation.condition();
}
Instruction create() {
checkConditionType();
try {
return createCondition();
} catch (RuntimeException re) {
throw re;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Instruction createCondition() throws Exception {
Instruction result;
if (isConditionTypeStandalone()) {
result = conditionType.newInstance();
} else {
result = conditionType.getDeclaredConstructor(mTestClass).newInstance(mTestClass);
}
return result;
}
private void checkConditionType() {
if (!isConditionTypeStandalone() && !isConditionTypeDeclaredInTarget()) {
String msg
= "Conditional class '%s' is a member class "
+ "but was not declared inside the test case using it.\n"
+ "Either make this class a static class, "
+ "standalone class (by declaring it in it's own file) "
+ "or move it inside the test case using it";
throw new IllegalArgumentException(String.format(msg, conditionType.getName()));
}
}
private boolean isConditionTypeStandalone() {
return !conditionType.isMemberClass()
|| Modifier.isStatic(conditionType.getModifiers());
}
private boolean isConditionTypeDeclaredInTarget() {
return mTestClass.getClass().isAssignableFrom(conditionType.getDeclaringClass());
}
}
private static class RunIfStatement extends Statement {
private Statement statement;
private Instruction condition;
RunIfStatement(Statement base, Instruction condition) {
statement = base;
this.condition = condition;
}
@Override
public void evaluate() throws Throwable {
if (condition.checkCondition()) {
statement.evaluate();
} else {
Timber.d("Ignored by " + condition.getClass().getSimpleName());
Assume.assumeTrue("Condition is: " + condition.checkCondition(), false);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment