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

Support programmatic extension registration via fields #497

Closed
3 tasks done
sbrannen opened this issue Sep 8, 2016 · 15 comments
Closed
3 tasks done

Support programmatic extension registration via fields #497

sbrannen opened this issue Sep 8, 2016 · 15 comments

Comments

@sbrannen
Copy link
Member

sbrannen commented Sep 8, 2016

Status Quo

It is currently possible to register extensions declaratively via @ExtendWith on a class or method but not on a field.

Furthermore, it is currently impossible for a user of an extension to provide input to the extension programmatically. Rather, in order to make an extension configurable, current extension implementations typically provide a custom annotation, but such an annotation is hindered by the limitations of what can be declared as an annotation attribute in Java.

See the discussion in Spring REST Docs for further background information.

Related Issues

Proposal for Programmatic Extension Registration

In general, it should be possible for an extension to be registered programmatically -- for example, via a field or a factory method. This would allow a user to pass arguments to the extension's constructor (or static factory method) or to construct the extension programmatically, for example, via a method that returns the configured extension instance.

With regard to migrations from JUnit 4 to JUnit Jupiter, it should be possible to migrate a JUnit 4 rule from this:

@Rule
public JUnitRestDocumentation restDocumentation =
        new JUnitRestDocumentation("target/generated-snippets");

... to the following in JUnit Jupiter:

@RegisterExtension
RestDocumentationExtension restDocumentation =
        new RestDocumentationExtension("target/generated-snippets");

Considerations

  • Although the existing @ExtendWith annotation could technically be repurposed for such use cases, the JUnit Team feels it would be better to introduce a new annotation dedicated to this purpose. The current proposed name is @RegisterExtension, but this may change.

Deliverables

  • Support programmatic registration of a single extension via a field annotated with @RegisterExtension where the field's value is used as the extension instance.
  • Document in User Guide.
  • Document in Release Notes.
@juergenzimmermann
Copy link

@sbrannen do you have a coarse estimation when M3 might be available?

@sbrannen
Copy link
Member Author

sbrannen commented Oct 3, 2016

@juergenzimmermann, perhaps by the end of October. The core team is swamped with work, so we are unfortunately forced to push back the release dates.

@SqAutoTestTeam
Copy link

We are migrating project from Juni4 to Junit5.
Some of functionality written in Juni4 is based on usage of Rule. The custom rule is used to
send tests results to outer system - where they can be seen later .

Rule provides me with three callback methods
protected void succeeded(Description desc);
protected void failed(Throwable e, Description desc);
protected void skipped(AssumptionViolatedException e, Description desc);

So I can be aware what is the test result - failed, success or skipped -
(AssumptionViolatedException exception is thrown while test execution)

@mmerdes has made a good work of adapting existing junit4 rules to extensions of junit5
but it does support method result callbacks unfortunately.

I've researched this topic and came to realise that for now there is no strait reliable way to implement this feature using only Junit5 extension model.

The closest extension is AfterTestExecutionCallback but its callback method
....
public void afterTestExecution(TestExtensionContext context) throws Exception
....
does not pass so necessary info - test execution result. So none can tell for sure
if test is ok, failed or ignored.
Indirect ways to solve this problem do not look reliable.

Now when you plan UseExtension my question is: Are you planning to provide users with test result callback or pass info of test result ? If not please take it into account. Sooner or later there will be users that encounter the same problem. Although I do not know implementation details I suppose that UseExtension as
a field annotation implies calling methods on field object it annotates.

Suggestion:
Possible solution is to add another Extension sub-interface (TestFinished) that passes test result into its callback method. In this case the task can be easily solved by writing custom extension.

@sbrannen
Copy link
Member Author

@SqAutoTestTeam, this issue focuses solely on programmatic extension registration via fields. Consequently, we are not considering any changes to extension APIs in conjunction with this issue.

If you would like to propose additional Extension APIs, please create a new issue dedicated to your proposal.

Thanks

@marcphilipp marcphilipp modified the milestones: 5.1+ Backlog, 5.0 M4 Dec 22, 2016
sbrannen added a commit that referenced this issue Mar 9, 2017
Prior to this commit, the MethodSortOrder enum was dedicated solely
for use with methods; however, once we implement #497 we will need
identical functionality for fields.

This commit addresses this issue by renaming MethodSortOrder to
HierarchyTraversalMode.

Issue: #716
@sbrannen sbrannen modified the milestones: 5.0 M5, 5.1+ Backlog Mar 13, 2017
@marcphilipp marcphilipp modified the milestones: 5.0 M5, 5.0 M6 May 6, 2017
@leonard84
Copy link
Collaborator

I'd like to add some wishes here:

  1. It should be possible to use injected extensions, e.g. via @Inject/@Autowired
  2. It should be possible for the test code to interact with the extension object similar to TemporaryFolder#newFile(String)

sbrannen added a commit that referenced this issue Jan 19, 2018
sbrannen added a commit that referenced this issue Jan 20, 2018
sbrannen added a commit that referenced this issue Jan 20, 2018
sbrannen added a commit that referenced this issue Jan 20, 2018
sbrannen added a commit that referenced this issue Jan 20, 2018
This commit introduces a test that verifies that a @RegisterExtension
field can be supplied by a dependency injection framework (e.g., the
Spring Framework, Guice, etc.) whose extension performs field injection
via the TestInstancePostProcessor API.

Issue: #497
sbrannen added a commit that referenced this issue Jan 20, 2018
@sbrannen
Copy link
Member Author

Feature branch merged into master in commit 4383792.

@ghost ghost removed the status: in progress label Jan 20, 2018
Andrei94 pushed a commit to Andrei94/junit5 that referenced this issue Jun 23, 2018
Andrei94 pushed a commit to Andrei94/junit5 that referenced this issue Jun 23, 2018
Andrei94 pushed a commit to Andrei94/junit5 that referenced this issue Jun 23, 2018
Andrei94 pushed a commit to Andrei94/junit5 that referenced this issue Jun 23, 2018
Andrei94 pushed a commit to Andrei94/junit5 that referenced this issue Jun 23, 2018
Andrei94 pushed a commit to Andrei94/junit5 that referenced this issue Jun 23, 2018
Andrei94 pushed a commit to Andrei94/junit5 that referenced this issue Jun 23, 2018
This commit introduces a test that verifies that a @RegisterExtension
field can be supplied by a dependency injection framework (e.g., the
Spring Framework, Guice, etc.) whose extension performs field injection
via the TestInstancePostProcessor API.

Issue: junit-team#497
Andrei94 pushed a commit to Andrei94/junit5 that referenced this issue Jun 23, 2018
Andrei94 pushed a commit to Andrei94/junit5 that referenced this issue Jun 23, 2018
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

5 participants