Skip to content

Commit

Permalink
Fall back to read Ignore annotation from test class
Browse files Browse the repository at this point in the history
  • Loading branch information
marcphilipp committed Sep 5, 2023
1 parent 37bb89e commit 103b29d
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import java.util.function.Consumer;

import org.apiguardian.api.API;
import org.junit.Ignore;
import org.junit.platform.commons.JUnitException;
import org.junit.platform.commons.logging.Logger;
import org.junit.platform.commons.logging.LoggerFactory;
Expand All @@ -44,14 +43,14 @@ public class RunnerTestDescriptor extends VintageTestDescriptor {

private final Set<Description> rejectedExclusions = new HashSet<>();
private Runner runner;
private final Optional<String> skipReason;
private final boolean ignored;
private boolean wasFiltered;
private List<Filter> filters = new ArrayList<>();

public RunnerTestDescriptor(UniqueId uniqueId, Class<?> testClass, Runner runner) {
public RunnerTestDescriptor(UniqueId uniqueId, Class<?> testClass, Runner runner, boolean ignored) {
super(uniqueId, runner.getDescription(), testClass.getSimpleName(), ClassSource.from(testClass));
this.runner = runner;
this.skipReason = Optional.ofNullable(testClass.getAnnotation(Ignore.class)).map(Ignore::value);
this.ignored = ignored;
}

@Override
Expand Down Expand Up @@ -158,8 +157,8 @@ private Runner getRunnerToReport() {
return (runner instanceof RunnerDecorator) ? ((RunnerDecorator) runner).getDecoratedRunner() : runner;
}

public Optional<String> getSkipReason() {
return skipReason;
public boolean isIgnored() {
return ignored;
}

private static class ExcludeDescriptionFilter extends Filter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,14 @@
import org.junit.platform.engine.discovery.UniqueIdSelector;
import org.junit.platform.engine.support.discovery.SelectorResolver;
import org.junit.runner.Runner;
import org.junit.runners.model.RunnerBuilder;
import org.junit.vintage.engine.descriptor.RunnerTestDescriptor;

/**
* @since 4.12
*/
class ClassSelectorResolver implements SelectorResolver {

private static final RunnerBuilder RUNNER_BUILDER = new DefensiveAllDefaultPossibilitiesBuilder();
private static final DefensiveAllDefaultPossibilitiesBuilder RUNNER_BUILDER = new DefensiveAllDefaultPossibilitiesBuilder();

private final ClassFilter classFilter;

Expand Down Expand Up @@ -76,7 +75,7 @@ private Resolution resolveTestClass(Class<?> testClass, Context context) {

private RunnerTestDescriptor createRunnerTestDescriptor(TestDescriptor parent, Class<?> testClass, Runner runner) {
UniqueId uniqueId = parent.getUniqueId().append(SEGMENT_TYPE_RUNNER, testClass.getName());
return new RunnerTestDescriptor(uniqueId, testClass, runner);
return new RunnerTestDescriptor(uniqueId, testClass, runner, RUNNER_BUILDER.isIgnored(runner));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ public Runner runnerForClass(Class<?> testClass) throws Throwable {
return runner;
}

boolean isIgnored(Runner runner) {
return runner instanceof IgnoredClassRunner || runner instanceof IgnoringRunnerDecorator;
}

/**
* Instead of checking for the {@link Ignore} annotation and returning an
* {@link IgnoredClassRunner} from {@link IgnoredBuilder}, we've let the
Expand All @@ -72,7 +76,7 @@ public Runner runnerForClass(Class<?> testClass) throws Throwable {
* override its runtime behavior (i.e. skip execution) but return its
* regular {@link org.junit.runner.Description}.
*/
private Runner decorateIgnoredTestClass(Runner runner) {
private IgnoringRunnerDecorator decorateIgnoredTestClass(Runner runner) {
if (runner instanceof Filterable) {
return new FilterableIgnoringRunnerDecorator(runner);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.junit.platform.engine.TestDescriptor;
import org.junit.platform.engine.TestExecutionResult;
import org.junit.platform.engine.UniqueId;
import org.junit.platform.engine.support.descriptor.ClassSource;
import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
Expand Down Expand Up @@ -49,7 +50,7 @@ class RunListenerAdapter extends RunListener {

@Override
public void testRunStarted(Description description) {
if (description.isSuite() && !testRun.getRunnerTestDescriptor().getSkipReason().isPresent()) {
if (description.isSuite() && !testRun.getRunnerTestDescriptor().isIgnored()) {
fireExecutionStarted(testRun.getRunnerTestDescriptor(), EventType.REPORTED);
}
}
Expand All @@ -66,7 +67,8 @@ public void testSuiteStarted(Description description) {
@Override
public void testIgnored(Description description) {
TestDescriptor testDescriptor = lookupOrRegisterNextTestDescriptor(description);
testIgnored(testDescriptor, determineReasonForIgnoredTest(description).orElse("<unknown>"));
String reason = determineReasonForIgnoredTest(testDescriptor, description).orElse("<unknown>");
testIgnored(testDescriptor, reason);
}

@Override
Expand Down Expand Up @@ -177,9 +179,21 @@ private void testIgnored(TestDescriptor testDescriptor, String reason) {
fireExecutionSkipped(testDescriptor, reason);
}

private Optional<String> determineReasonForIgnoredTest(Description description) {
Optional<String> reason = Optional.ofNullable(description.getAnnotation(Ignore.class)).map(Ignore::value);
return reason.isPresent() ? reason : testRun.getRunnerTestDescriptor().getSkipReason();
private Optional<String> determineReasonForIgnoredTest(TestDescriptor testDescriptor, Description description) {
Optional<String> reason = getReason(description.getAnnotation(Ignore.class));
if (reason.isPresent()) {
return reason;
}
// Workaround for some runners (e.g. JUnit38ClassRunner) don't include the @Ignore annotation
// in the description, so we read it from the test class directly
return testDescriptor.getSource() //
.filter(ClassSource.class::isInstance) //
.map(source -> ((ClassSource) source).getJavaClass()) //
.flatMap(testClass -> getReason(testClass.getAnnotation(Ignore.class)));
}

private static Optional<String> getReason(Ignore annotation) {
return Optional.ofNullable(annotation).map(Ignore::value);
}

private void dynamicTestRegistered(TestDescriptor testDescriptor) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ class TestRunTests {
void returnsEmptyOptionalForUnknownDescriptions() throws Exception {
Class<?> testClass = PlainJUnit4TestCaseWithSingleTestWhichFails.class;
var runnerId = engineId().append(SEGMENT_TYPE_RUNNER, testClass.getName());
var runnerTestDescriptor = new RunnerTestDescriptor(runnerId, testClass, new BlockJUnit4ClassRunner(testClass));
var runnerTestDescriptor = new RunnerTestDescriptor(runnerId, testClass, new BlockJUnit4ClassRunner(testClass),
false);
var unknownDescription = createTestDescription(testClass, "dynamicTest");

var testRun = new TestRun(runnerTestDescriptor);
Expand All @@ -45,7 +46,8 @@ void returnsEmptyOptionalForUnknownDescriptions() throws Exception {
void registersDynamicTestDescriptors() throws Exception {
Class<?> testClass = PlainJUnit4TestCaseWithSingleTestWhichFails.class;
var runnerId = engineId().append(SEGMENT_TYPE_RUNNER, testClass.getName());
var runnerTestDescriptor = new RunnerTestDescriptor(runnerId, testClass, new BlockJUnit4ClassRunner(testClass));
var runnerTestDescriptor = new RunnerTestDescriptor(runnerId, testClass, new BlockJUnit4ClassRunner(testClass),
false);
var dynamicTestId = runnerId.append(SEGMENT_TYPE_DYNAMIC, "dynamicTest");
var dynamicDescription = createTestDescription(testClass, "dynamicTest");
var dynamicTestDescriptor = new VintageTestDescriptor(dynamicTestId, dynamicDescription, null);
Expand Down

0 comments on commit 103b29d

Please sign in to comment.