Skip to content

Commit

Permalink
Manually add @Ignore annotation to the JUnit38ClassRunner root de…
Browse files Browse the repository at this point in the history
…scription
  • Loading branch information
pshevche committed Aug 15, 2023
1 parent 32a6465 commit ea3e7df
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,12 @@ class DefensiveAllDefaultPossibilitiesBuilder extends AllDefaultPossibilitiesBui
@Override
public Runner runnerForClass(Class<?> testClass) throws Throwable {
Runner runner = super.runnerForClass(testClass);
if (testClass.getAnnotation(Ignore.class) != null) {
Ignore ignoreAnnotation = testClass.getAnnotation(Ignore.class);
if (ignoreAnnotation != null) {
if (runner == null) {
return new IgnoredClassRunner(testClass);
}
return decorateIgnoredTestClass(runner);
return decorateIgnoredTestClass(runner, ignoreAnnotation);
}
return runner;
}
Expand All @@ -72,11 +73,11 @@ 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 Runner decorateIgnoredTestClass(Runner runner, Ignore ignoreAnnotation) {
if (runner instanceof Filterable) {
return new FilterableIgnoringRunnerDecorator(runner);
return new FilterableIgnoringRunnerDecorator(runner, ignoreAnnotation);
}
return new IgnoringRunnerDecorator(runner);
return new IgnoringRunnerDecorator(runner, ignoreAnnotation);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

package org.junit.vintage.engine.discovery;

import org.junit.Ignore;
import org.junit.platform.commons.util.Preconditions;
import org.junit.runner.Runner;
import org.junit.runner.manipulation.Filter;
Expand All @@ -23,8 +24,8 @@
*/
class FilterableIgnoringRunnerDecorator extends IgnoringRunnerDecorator implements Filterable {

FilterableIgnoringRunnerDecorator(Runner runner) {
super(runner);
FilterableIgnoringRunnerDecorator(Runner runner, Ignore ignoreAnnotation) {
super(runner, ignoreAnnotation);
Preconditions.condition(runner instanceof Filterable,
() -> "Runner must be an instance of Filterable: " + runner.getClass().getName());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,20 @@

package org.junit.vintage.engine.discovery;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;

import org.junit.Ignore;
import org.junit.internal.runners.JUnit38ClassRunner;
import org.junit.platform.commons.logging.Logger;
import org.junit.platform.commons.logging.LoggerFactory;
import org.junit.platform.commons.util.Preconditions;
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.notification.RunNotifier;
import org.junit.vintage.engine.descriptor.RunnerDecorator;
import org.junit.vintage.engine.descriptor.RunnerTestDescriptor;

/**
* Decorator for Runners that will be ignored completely.
Expand All @@ -26,15 +35,29 @@
*/
class IgnoringRunnerDecorator extends Runner implements RunnerDecorator {

private static final Logger logger = LoggerFactory.getLogger(RunnerTestDescriptor.class);

protected final Runner runner;
private final Ignore testClassIgnoreAnnotation;

IgnoringRunnerDecorator(Runner runner) {
IgnoringRunnerDecorator(Runner runner, Ignore ignoreAnnotation) {
this.runner = Preconditions.notNull(runner, "Runner must not be null");
this.testClassIgnoreAnnotation = Preconditions.notNull(ignoreAnnotation,
"Test class @Ignore annotation must not be null");
}

@Override
public Description getDescription() {
return runner.getDescription();
Description originalDescription = runner.getDescription();

if (runner instanceof JUnit38ClassRunner) {
return junit38ClassRunnerDescriptionWithIgnoreAnnotation(originalDescription);
}
else if (originalDescription.getAnnotation(Ignore.class) == null) {
warnAboutMissingIgnoreAnnotation(originalDescription);
}

return originalDescription;
}

@Override
Expand All @@ -46,4 +69,26 @@ public void run(RunNotifier notifier) {
public Runner getDecoratedRunner() {
return runner;
}

/**
* {@link JUnit38ClassRunner} does not add class-level annotations to the runner description,
* which results in an inconsistent behavior when combined with the vintage engine: the runner description
* will be marked as started because the runner told so, but it will alos be reported as skipped by IgnoringRunnerDecorator
* which detected the @Ignore annotation on the test Java class.
*/
private Description junit38ClassRunnerDescriptionWithIgnoreAnnotation(Description runnerDescription) {
List<Annotation> effectiveAnnotations = new ArrayList<>(runnerDescription.getAnnotations());
effectiveAnnotations.add(testClassIgnoreAnnotation);

Description updatedRunnerDescription = Description.createTestDescription(runnerDescription.getClassName(),
runnerDescription.getMethodName(), effectiveAnnotations.toArray(new Annotation[0]));

runnerDescription.getChildren().forEach(updatedRunnerDescription::addChild);
return updatedRunnerDescription;
}

private void warnAboutMissingIgnoreAnnotation(Description originalDescription) {
logger.warn(() -> "Custom test runner '" + runner.getClass().getName()
+ "' did not add an @Ignore annotation to the runner description " + originalDescription);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@ void executesIgnoredJUnit3TestCase() {
var suiteClass = IgnoredJUnit3TestCase.class;
execute(suiteClass).allEvents().assertEventsMatchExactly( //
event(engine(), started()), //
event(container(suiteClass), skippedWithReason(__ -> true)), //
event(container(suiteClass), skippedWithReason("respected by Vintage engine")), //
event(engine(), finishedSuccessfully()));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
/**
* @since 4.12
*/
@Ignore
@Ignore("respected by Vintage engine")
public class IgnoredJUnit3TestCase extends TestCase {

public void test() {
Expand Down

0 comments on commit ea3e7df

Please sign in to comment.