Skip to content

Instantly share code, notes, and snippets.

@alexengrig
Last active November 14, 2022 09:47
Show Gist options
  • Save alexengrig/a4c8c49d5aa3aeca0ce78368a7987fb3 to your computer and use it in GitHub Desktop.
Save alexengrig/a4c8c49d5aa3aeca0ce78368a7987fb3 to your computer and use it in GitHub Desktop.
JUnit 5: Enable/disable test on master branche

Skip test on master

@DisabledOnBranch("master")

Skip test on not master

@EnabledOnBranch("master")

import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.platform.commons.util.AnnotationUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.Arrays;
import java.util.Optional;
abstract class BaseFlagOnBranchCondition<A extends Annotation> implements ExecutionCondition {
private final Class<A> annotationType;
private final boolean enabled;
BaseFlagOnBranchCondition(Class<A> annotationType, boolean enabled) {
this.annotationType = annotationType;
this.enabled = enabled;
}
protected abstract String[] branches(A annotation);
@Override
public final ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
AnnotatedElement element = context.getElement().orElseThrow(() -> new IllegalStateException("No element"));
return AnnotationUtils.findAnnotation(element, annotationType)
.map(annotation -> evaluate(annotation, element))
.orElseGet(this::createDefaultResult);
}
private ConditionEvaluationResult evaluate(A annotation, AnnotatedElement element) {
Optional<String> optionalBranch = getCurrentBranch();
if (optionalBranch.isEmpty()) {
return enabled
? ConditionEvaluationResult.disabled(
element + " is disabled because current Git branch could not be discover")
: ConditionEvaluationResult.enabled(
element + " is enabled because current Git branch could not be discover");
}
String branch = optionalBranch.get();
String[] branches = branches(annotation);
if (isExpectedBranch(branch, branches)) {
return enabled
? ConditionEvaluationResult.enabled(
element +
" is enabled because current Git branch '" + branch +
"' is in expected: " + Arrays.toString(branches))
: ConditionEvaluationResult.disabled(
element +
" is disabled because current Git branch '" + branch +
"' is in expected: " + Arrays.toString(branches));
} else {
return enabled
? ConditionEvaluationResult.disabled(
element +
" is disabled because current Git branch '" + branch +
"' is not in expected: " + Arrays.toString(branches))
: ConditionEvaluationResult.enabled(
element +
" is enabled because current Git branch '" + branch +
"' is not in expected: " + Arrays.toString(branches));
}
}
private Optional<String> getCurrentBranch() {
try {
String command = "git branch --show-current";
Process process = Runtime.getRuntime().exec(command);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
String output = stdInput.readLine();
return Optional.of(output);
} catch (IOException ignore) {
return Optional.empty();
}
}
private boolean isExpectedBranch(String branch, String[] branches) {
boolean expected = false;
for (String b : branches) {
if (branch.equals(b)) {
expected = true;
break;
}
}
return expected;
}
private ConditionEvaluationResult createDefaultResult() {
String reason = "@" + annotationType.getSimpleName() + " is not present";
return enabled
? ConditionEvaluationResult.enabled(reason)
: ConditionEvaluationResult.disabled(reason);
}
}
import org.junit.jupiter.api.extension.ExtendWith;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(DisabledOnBranchCondition.class)
public @interface DisabledOnBranch {
String[] value();
}
class DisabledOnBranchCondition extends BaseFlagOnBranchCondition<DisabledOnBranch> {
DisabledOnBranchCondition() {
super(DisabledOnBranch.class, false);
}
@Override
protected String[] branches(DisabledOnBranch annotation) {
return annotation.value();
}
}
import org.junit.jupiter.api.extension.ExtendWith;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(EnabledOnBranchCondition.class)
public @interface EnabledOnBranch {
String[] value() default {"master"};
}
class EnabledOnBranchCondition extends BaseFlagOnBranchCondition<EnabledOnBranch> {
EnabledOnBranchCondition() {
super(EnabledOnBranch.class, true);
}
@Override
protected String[] branches(EnabledOnBranch annotation) {
return annotation.value();
}
}
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import ru.spb.iac.isiao.apidoc.starter.test.util.DisabledOnBranch;
import ru.spb.iac.isiao.apidoc.starter.test.util.EnabledOnBranch;
class FooTest {
@Test
@DisabledOnBranch("master")
void should_skip_on_master() {
Assertions.fail("not master");
}
@Test
@EnabledOnBranch("master")
void should_fail_on_master() {
Assertions.fail("master");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment