Skip to content

Commit 7eb0eb7

Browse files
committed
Report discovery issue for competing test method annotations
Issue: #242
1 parent 22836eb commit 7eb0eb7

File tree

6 files changed

+40
-41
lines changed

6 files changed

+40
-41
lines changed

junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/discovery/DiscoverySelectorResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class DiscoverySelectorResolver {
4040
private static final EngineDiscoveryRequestResolver<JupiterEngineDescriptor> resolver = EngineDiscoveryRequestResolver.<JupiterEngineDescriptor> builder() //
4141
.addClassContainerSelectorResolver(new IsTestClassWithTests()) //
4242
.addSelectorResolver(ctx -> new ClassSelectorResolver(ctx.getClassNameFilter(), getConfiguration(ctx))) //
43-
.addSelectorResolver(ctx -> new MethodSelectorResolver(getConfiguration(ctx))) //
43+
.addSelectorResolver(ctx -> new MethodSelectorResolver(getConfiguration(ctx), ctx.getIssueReporter())) //
4444
.addTestDescriptorVisitor(ctx -> TestDescriptor.Visitor.composite( //
4545
new ClassOrderingVisitor(getConfiguration(ctx)), //
4646
new MethodOrderingVisitor(getConfiguration(ctx)), //

junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/discovery/MethodSelectorResolver.java

+16-13
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@
4141
import org.junit.jupiter.engine.discovery.predicates.IsTestFactoryMethod;
4242
import org.junit.jupiter.engine.discovery.predicates.IsTestMethod;
4343
import org.junit.jupiter.engine.discovery.predicates.IsTestTemplateMethod;
44-
import org.junit.platform.commons.logging.Logger;
45-
import org.junit.platform.commons.logging.LoggerFactory;
4644
import org.junit.platform.commons.util.ClassUtils;
45+
import org.junit.platform.engine.DiscoveryIssue;
46+
import org.junit.platform.engine.DiscoveryIssue.Severity;
4747
import org.junit.platform.engine.DiscoverySelector;
4848
import org.junit.platform.engine.TestDescriptor;
4949
import org.junit.platform.engine.UniqueId;
@@ -52,22 +52,25 @@
5252
import org.junit.platform.engine.discovery.MethodSelector;
5353
import org.junit.platform.engine.discovery.NestedMethodSelector;
5454
import org.junit.platform.engine.discovery.UniqueIdSelector;
55+
import org.junit.platform.engine.support.descriptor.MethodSource;
56+
import org.junit.platform.engine.support.discovery.DiscoveryIssueReporter;
5557
import org.junit.platform.engine.support.discovery.SelectorResolver;
5658

5759
/**
5860
* @since 5.5
5961
*/
6062
class MethodSelectorResolver implements SelectorResolver {
6163

62-
private static final Logger logger = LoggerFactory.getLogger(MethodSelectorResolver.class);
6364
private static final MethodFinder methodFinder = new MethodFinder();
6465
private static final Predicate<Class<?>> testClassPredicate = new IsTestClassWithTests().or(
6566
new IsNestedTestClass());
6667

67-
protected final JupiterConfiguration configuration;
68+
private final JupiterConfiguration configuration;
69+
private final DiscoveryIssueReporter issueReporter;
6870

69-
MethodSelectorResolver(JupiterConfiguration configuration) {
71+
MethodSelectorResolver(JupiterConfiguration configuration, DiscoveryIssueReporter issueReporter) {
7072
this.configuration = configuration;
73+
this.issueReporter = issueReporter;
7174
}
7275

7376
@Override
@@ -97,14 +100,14 @@ private Resolution resolve(Context context, List<Class<?>> enclosingClasses, Cla
97100
.collect(toSet());
98101
// @formatter:on
99102
if (matches.size() > 1) {
100-
logger.warn(() -> {
101-
Stream<TestDescriptor> testDescriptors = matches.stream().map(Match::getTestDescriptor);
102-
return String.format(
103-
"Possible configuration error: method [%s] resulted in multiple TestDescriptors %s. "
104-
+ "This is typically the result of annotating a method with multiple competing annotations "
105-
+ "such as @Test, @RepeatedTest, @ParameterizedTest, @TestFactory, etc.",
106-
method.toGenericString(), testDescriptors.map(d -> d.getClass().getName()).collect(toList()));
107-
});
103+
Stream<TestDescriptor> testDescriptors = matches.stream().map(Match::getTestDescriptor);
104+
String message = String.format(
105+
"Possible configuration error: method [%s] resulted in multiple TestDescriptors %s. "
106+
+ "This is typically the result of annotating a method with multiple competing annotations "
107+
+ "such as @Test, @RepeatedTest, @ParameterizedTest, @TestFactory, etc.",
108+
method.toGenericString(), testDescriptors.map(d -> d.getClass().getName()).collect(toList()));
109+
issueReporter.reportIssue(
110+
DiscoveryIssue.builder(Severity.WARNING, message).source(MethodSource.from(method)));
108111
}
109112
return matches.isEmpty() ? unresolved() : matches(matches);
110113
}

junit-platform-engine/src/main/java/org/junit/platform/engine/support/discovery/EngineDiscoveryRequestResolution.java

-6
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030

3131
import org.junit.platform.commons.JUnitException;
3232
import org.junit.platform.commons.util.UnrecoverableExceptions;
33-
import org.junit.platform.engine.DiscoveryIssue;
3433
import org.junit.platform.engine.DiscoverySelector;
3534
import org.junit.platform.engine.EngineDiscoveryListener;
3635
import org.junit.platform.engine.EngineDiscoveryRequest;
@@ -262,11 +261,6 @@ private <T extends TestDescriptor> Optional<T> createAndAdd(TestDescriptor paren
262261
return child;
263262
}
264263

265-
@Override
266-
public void reportIssue(DiscoveryIssue issue) {
267-
issueReporter.reportIssue(issue);
268-
}
269-
270264
}
271265

272266
}

junit-platform-engine/src/main/java/org/junit/platform/engine/support/discovery/SelectorResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ default Resolution resolve(DiscoverySelector selector, Context context) {
357357
* @see SelectorResolver
358358
*/
359359
@API(status = STABLE, since = "1.10")
360-
interface Context extends DiscoveryIssueReporter {
360+
interface Context {
361361

362362
/**
363363
* Resolve the supplied {@link TestDescriptor}, if possible.

jupiter-tests/src/test/java/org/junit/jupiter/engine/MultipleTestableAnnotationsTests.java

+18-17
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,15 @@
1010

1111
package org.junit.jupiter.engine;
1212

13-
import static org.junit.jupiter.api.Assertions.assertTrue;
14-
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
15-
import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request;
16-
17-
import java.util.logging.Level;
18-
import java.util.logging.LogRecord;
13+
import static org.assertj.core.api.Assertions.assertThat;
14+
import static org.junit.jupiter.api.Assertions.assertNotNull;
15+
import static org.junit.platform.commons.util.CollectionUtils.getOnlyElement;
1916

2017
import org.junit.jupiter.api.RepeatedTest;
2118
import org.junit.jupiter.api.RepetitionInfo;
2219
import org.junit.jupiter.api.Test;
23-
import org.junit.jupiter.api.fixtures.TrackLogRecords;
24-
import org.junit.platform.commons.logging.LogRecordListener;
20+
import org.junit.platform.engine.DiscoveryIssue.Severity;
21+
import org.junit.platform.engine.support.descriptor.MethodSource;
2522

2623
/**
2724
* Integration tests that verify the correct behavior for methods annotated
@@ -32,23 +29,27 @@
3229
class MultipleTestableAnnotationsTests extends AbstractJupiterTestEngineTests {
3330

3431
@Test
35-
void testAndRepeatedTest(@TrackLogRecords LogRecordListener listener) {
36-
discoverTests(request().selectors(selectClass(TestCase.class)).build());
37-
38-
// @formatter:off
39-
assertTrue(listener.stream(Level.WARNING)
40-
.map(LogRecord::getMessage)
41-
.anyMatch(m -> m.matches("Possible configuration error: method .+ resulted in multiple TestDescriptors .+")));
42-
// @formatter:on
32+
void testAndRepeatedTest() throws Exception {
33+
var results = discoverTestsForClass(TestCase.class);
34+
35+
var discoveryIssue = getOnlyElement(results.getDiscoveryIssues());
36+
37+
assertThat(discoveryIssue.severity()) //
38+
.isEqualTo(Severity.WARNING);
39+
assertThat(discoveryIssue.message()) //
40+
.matches("Possible configuration error: method .+ resulted in multiple TestDescriptors .+");
41+
assertThat(discoveryIssue.source()) //
42+
.contains(
43+
MethodSource.from(TestCase.class.getDeclaredMethod("testAndRepeatedTest", RepetitionInfo.class)));
4344
}
4445

4546
@SuppressWarnings("JUnitMalformedDeclaration")
4647
static class TestCase {
4748

48-
@SuppressWarnings("JUnitMalformedDeclaration")
4949
@Test
5050
@RepeatedTest(1)
5151
void testAndRepeatedTest(RepetitionInfo repetitionInfo) {
52+
assertNotNull(repetitionInfo);
5253
}
5354

5455
}

platform-tests/src/test/java/org/junit/platform/engine/support/discovery/EngineDiscoveryRequestResolverTests.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ public class EngineDiscoveryRequestResolverTests {
3131
@Test
3232
void allowsSelectorResolversToReportDiscoveryIssues() {
3333
var resolver = EngineDiscoveryRequestResolver.builder() //
34-
.addSelectorResolver(new SelectorResolver() {
34+
.addSelectorResolver(ctx -> new SelectorResolver() {
3535
@Override
3636
public Resolution resolve(ClassSelector selector, Context context) {
37-
context.reportIssue(DiscoveryIssue.builder(NOTICE, "test") //
38-
.source(ClassSource.from(selector.getClassName())));
37+
ctx.getIssueReporter() //
38+
.reportIssue(DiscoveryIssue.builder(NOTICE, "test") //
39+
.source(ClassSource.from(selector.getClassName())));
3940
return unresolved();
4041
}
4142
}) //

0 commit comments

Comments
 (0)