Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inheritance support for conditional annotations #4147

Open
1 task
scordio opened this issue Nov 22, 2024 · 8 comments
Open
1 task

Inheritance support for conditional annotations #4147

scordio opened this issue Nov 22, 2024 · 8 comments

Comments

@scordio
Copy link
Contributor

scordio commented Nov 22, 2024

I faced a use case where inheritance for @EnabledIfSystemProperty would have helped for less boilerplate.

Specifically, it's a project with many test classes for integration tests that should be executed only on the CI infrastructure and specific runners. Such fine-grained control is currently achieved combining the maven-failsafe-plugin to exclude the local environment and @EnabledIfSystemProperty(named = "it.test", matches = ".+") on each test class to ensure that they are executed only under the appropriate CI jobs (the it.test property is set to different values by each CI job to tune the failsafe plugin execution further).

As the test classes already share common parts in a parent class, pulling @EnabledIfSystemProperty to the parent class would help reduce the boilerplate.

Relates to #3462 (comment).

Deliverables

  • Conditional annotations support inheritance
@marcphilipp
Copy link
Member

Thinking out loud here, I think we have at least the following options:

  1. Make the existing annotations @Inherited
  2. Add a variant for each annotation that is @Inherited
  3. Change the annotation search algorithm for test classes to check parent classes as well

Both (1) and (3) would be breaking changes. For (2), I think we could generate the @Inherited variant, and add some glue code that uses a java.lang.reflect.Proxy so the majority of the code wouldn't have to change.

Any other ideas?

@scordio
Copy link
Contributor Author

scordio commented Nov 27, 2024

Change the annotation search algorithm for test classes to check parent classes as well

To avoid the breaking change, can this be combined with a new opt-in flag for the current annotations, false by default? Something like in inherited=true or similar.

@marcphilipp
Copy link
Member

Team decision: Wait for additional interest from the community.

@vdmitrienko
Copy link
Contributor

vdmitrienko commented Feb 23, 2025

+1 upvote

I recently faced a similar use case with the @DisabledOnOs annotation. I was 99% sure I could simply place it on a base class, but discovered that the annotation is not inherited.

The approach suggested by @scordio looks great to me.

@marcphilipp @scordio, if you don't mind, I’d be happy to submit a PR if you decide to implement this.

@sbrannen
Copy link
Member

sbrannen commented Feb 23, 2025

To avoid the breaking change, can this be combined with a new opt-in flag for the current annotations, false by default? Something like in inherited=true or similar.

That would certainly be an option, and it's similar to what I did for several test-related annotations in the Spring Framework (for example, @TestExecutionListeners(inheritListeners = false), @ActiveProfiles(inheritProfiles = false), @ContextConfiguration(inheritLocations = false), @ContextCustomizerFactories(inheritFactories = false) etc.).

However, there's a difference: all of those inherit* flags in Spring default to true, and that changes the programming model slightly. But you'd end up with effectively the same level of opt-in support.

If we introduce inherit* flags in JUnit Jupiter, they would have to be set manually for all conditional annotations. So, another option would be to introduce something like @InheritConditions (with a boolean value() default true attribute) that applies to all conditional annotations on the current type and its subtypes. @InheritConditions could of course be declared on a subtype to override the inherited @InheritConditions configuration.

I'm simply "playing devil's advocate" here to ensure we think about multiple use cases.

@sbrannen
Copy link
Member

+1 upvote

@vdmitrienko, in case you meant to up-vote this feature request, we use the 👍 emoji "reaction" on the issue description to track that.

@vdmitrienko
Copy link
Contributor

@vdmitrienko, in case you meant to up-vote this feature request, we use the 👍 emoji "reaction" on the issue description to track that.

Thanks @sbrannen !

@vdmitrienko
Copy link
Contributor

That would certainly be an option, and it's similar to what I did for several test-related annotations in the Spring Framework (for example, @TestExecutionListeners(inheritListeners = false), @ActiveProfiles(inheritProfiles = false), @ContextConfiguration(inheritLocations = false), @ContextCustomizerFactories(inheritFactories = false) etc.).

@sbrannen, this brings me to the following thoughts:

Perhaps, from a maintenance standpoint, using @InheritConditions could be a slightly better option. If the "conditional" annotations default to inherited=false, then, for consistency, any future annotations with such a flag should also default to false. However, with @InheritConditions, there is no obligation to maintain that consistency, providing the flexibility to use inherited=true as the default in the future.

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

No branches or pull requests

4 participants