Skip to content

Conversation

@marcphilipp
Copy link
Member

Overview

This is a proof-of-concept draft for #242 to get early feedback on the API.


I hereby agree to the terms of the JUnit Contributor License Agreement.


Definition of Done

default void selectorProcessed(UniqueId engineId, DiscoverySelector selector, SelectorResolutionResult result) {
}

default void issueFound(UniqueId engineId, EngineDiscoveryIssue issue) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 This is the top-level API for engines to report discovery issues.

Comment on lines 79 to 84
Set<Severity> failureIssueSeverities = Arrays.stream(configValue.split(",")) //
.map(Severity::valueOf) // TODO case-insensitive parsing
.collect(toCollection(() -> EnumSet.noneOf(Severity.class)));
// TODO Collect errors and throw exception or log all issues
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 The idea here is that the default abortOnFailure listener would treat the configured issue severities as failures and throw an exception containing all of them after the launcher has finished test discovery. In 5.13 the list would be empty (?) but in 6.0 we could make it strict and fail on deprecations and warnings.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, a discovery listener could collect all issues and report the engine descriptor as failed during execution.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 106 to 107
context.reportIssue(EngineDiscoveryIssue.builder(Severity.NOTICE, message) //
.selector(selector) //
.source(MethodSource.from(testClass, method)));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 Engines using the EngineDiscoveryRequestResolver framework work discovery can report issues via the Context passed to each SelectorResolver.

.addTestDescriptorVisitor(ctx -> new MethodOrderingVisitor(getConfiguration(ctx))) //
.addTestDescriptorVisitor(ctx -> new ClassOrderingVisitor(ctx.getIssueReporter(), getConfiguration(ctx))) //
.addTestDescriptorVisitor(ctx -> new MethodOrderingVisitor(ctx.getIssueReporter(), getConfiguration(ctx))) //
.addTestDescriptorVisitor(ctx -> new ValidatingVisitor(ctx.getIssueReporter())) //
Copy link
Member Author

@marcphilipp marcphilipp Mar 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 Visitors registered via EngineDiscoveryRequestResolver can use the DiscoveryIssueReporter to report issues.

Comment on lines +31 to +33
if (descriptor instanceof Validatable) {
((Validatable) descriptor).validate(new Reporter(descriptor));
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 Engines such as Jupiter can use any custom logic to validate during discovery. Here a visitor is used that checks for the Jupiter-specific Validatable marker interface.

Comment on lines +158 to +162
afterAllMethods.stream() //
.filter(ModifierSupport::isPrivate) //
.forEach(method -> reporter.reportIssue(Severity.DEPRECATION,
String.format("@AfterAll method [%s] should not be private.", method.toGenericString()),
b -> b.source(MethodSource.from(method))));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 Example of a engine-specific "post-discovery" validation that reports private lifecycle methods as deprecated (also would need to be done for @BeforeEach etc.).

Comment on lines 200 to 202
AbstractOrderingVisitor.this.issueReporter //
.reportIssue(EngineDiscoveryIssue.builder(Severity.WARNING, message) //
.source(parentTestDescriptor.getSource()));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 Another example of a custom "post-discovery" validation that reports a warning for issues during class/method ordering.

@marcphilipp marcphilipp force-pushed the marc/242-discovery-issues branch from 07b8259 to f848139 Compare March 10, 2025 14:42
@marcphilipp marcphilipp force-pushed the marc/242-discovery-issues branch from f848139 to 7827335 Compare March 10, 2025 14:56
Copy link
Contributor

@leonard84 leonard84 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some preliminary comments


void validate(IssueReporter issueReporter);

interface IssueReporter {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚲🏠 Why did you choose issue instead of problem?

Copy link
Contributor

@mpkorstanje mpkorstanje left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks very workable. It would cover all use cases Cucumber has for it now.

@marcphilipp marcphilipp linked an issue Mar 11, 2025 that may be closed by this pull request
36 tasks
@marcphilipp marcphilipp force-pushed the marc/242-discovery-issues branch from 6f121de to 09ddba0 Compare March 11, 2025 13:40
@marcphilipp
Copy link
Member Author

Alternatively, a discovery listener could collect all issues and report the engine descriptor as failed during execution.

I've spiked that approach. Here are the preliminary results:

Gradle

gradle
gradle-html-report

Maven

maven

IntelliJ

intellij

Run via Gradle

gradle-in-intellij

Eclipse

eclipse

@leonard84
Copy link
Contributor

Was this just for testing, or will deprecations fail the discovery? IMHO, only Severity.ERROR should cause a failure unless you set something like the equivalent of -Werror.

@sbrannen
Copy link
Member

Was this just for testing, or will deprecations fail the discovery? IMHO, only Severity.ERROR should cause a failure unless you set something like the equivalent of -Werror.

That was just for testing.

We haven't yet decided what severity would fail the build, and that may differ in 5.x and 6.0.

We also plan to make it configurable.

@marcphilipp
Copy link
Member Author

Correct, that was just for testing. All "non-critical" issues (depending on the severity configured as "critical") will just be logged.

@marcphilipp marcphilipp force-pushed the marc/242-discovery-issues branch from 08b24e0 to a89235c Compare March 13, 2025 08:37
@marcphilipp
Copy link
Member Author

Superseded by #4385

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants