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

Introduce extension API for container templates #4315

Merged
merged 61 commits into from
Feb 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
f3146ab
Add initial API and failing test
marcphilipp Jan 28, 2025
85116da
Implement discovery by class selector
marcphilipp Jan 28, 2025
f2871c3
Add container template support for testable methods
marcphilipp Jan 28, 2025
fce9386
Register all descendants of a template invocation as dynamic tests
marcphilipp Jan 28, 2025
e8ec031
Add support for `Nested` classes inside container templates
marcphilipp Jan 30, 2025
031e573
Delete unused code
marcphilipp Jan 30, 2025
3240af9
Add tests for method selectors
marcphilipp Jan 30, 2025
27e6575
Add support for applying `PostDiscoveryFilters`
marcphilipp Jan 30, 2025
15cda8a
Prune empty nested containers
marcphilipp Feb 3, 2025
2da3294
Add support for nested container templates
marcphilipp Feb 3, 2025
443f3dc
Add support for nesting container templates
marcphilipp Feb 3, 2025
7fc0cef
Improve tests
marcphilipp Feb 3, 2025
6a392fe
Allow context providers to register additional extensions
marcphilipp Feb 3, 2025
719b122
Allow invocation context to be garbage-collected
marcphilipp Feb 4, 2025
2611f6c
Avoid class-level extension context from being closed prematurely
marcphilipp Feb 4, 2025
217a8aa
Verify combination with test template methods
marcphilipp Feb 4, 2025
8f41b45
Verify combination with test factory methods
marcphilipp Feb 4, 2025
bb86744
Verify validation of zero provided invocation contexts
marcphilipp Feb 4, 2025
2a7da23
Verify validation of registered providers
marcphilipp Feb 4, 2025
6988b0a
Add support for discovering container templates by unique ID
marcphilipp Feb 4, 2025
38716de
Add support for discovering single invocation by unique ID
marcphilipp Feb 4, 2025
560bf91
Allow selecting a container template invocation by unique ID
marcphilipp Feb 4, 2025
9a18980
Add support for unique-id-based discovery of nested classes/methods
marcphilipp Feb 6, 2025
d090fb3
Add support for unique-id-based discovery of nested container templates
marcphilipp Feb 6, 2025
1190bf9
Remove duplication
marcphilipp Feb 6, 2025
eb82e8e
Add test for filtering
marcphilipp Feb 6, 2025
d7c3132
Ensure `ContainerTemplateTestDescriptor.prune()` is idempotent
marcphilipp Feb 6, 2025
22809aa
Polishing
marcphilipp Feb 6, 2025
811d6e8
Make method private again
marcphilipp Feb 6, 2025
dce6412
Make things private again
marcphilipp Feb 6, 2025
a6fc494
Polishing
marcphilipp Feb 6, 2025
c180159
Add support for discovering static container templates by iteration
marcphilipp Feb 6, 2025
6af1a48
Add support for discovering nested container templates by iteration
marcphilipp Feb 6, 2025
e661aa2
Implement getLegacyReportingName()
marcphilipp Feb 9, 2025
cb19c78
Update build tool integration tests to use container templates
marcphilipp Feb 9, 2025
19116a4
Avoid exception when logging the condition evaluation result
marcphilipp Feb 10, 2025
fc1c0f6
Avoid evaluating conditions for container template invocations
marcphilipp Feb 10, 2025
6bd909b
Add tests for class ordering with container templates
marcphilipp Feb 10, 2025
fcbb07d
Add test for method ordering with container templates
marcphilipp Feb 10, 2025
3c12908
Test integration with `TestInstance.Lifecycle`
marcphilipp Feb 10, 2025
f165c0b
Disable stack trace pruning to ease reasoning about test failures
marcphilipp Feb 10, 2025
095fee6
Remove constructor only used in tests
marcphilipp Feb 10, 2025
e31391c
Introduce special extension context for container template invocations
marcphilipp Feb 10, 2025
23bb589
Pull up exclusive resources to container template descriptor
marcphilipp Feb 10, 2025
817b622
Collect exclusive resources from nested container templates
marcphilipp Feb 11, 2025
fb3d5e8
Use TestClassAware where possible
marcphilipp Feb 11, 2025
c75d9de
Fix integration with `DisplayNameGeneration`
marcphilipp Feb 11, 2025
e295088
Verify test template invocation selection inside container template
marcphilipp Feb 11, 2025
a6c1d4e
Verify dynamic test selection inside container template
marcphilipp Feb 11, 2025
d60eb13
Move container template in integration test to separate class
marcphilipp Feb 11, 2025
1ef6082
Add regular test method to container template integration test
marcphilipp Feb 11, 2025
a431915
Verify Gradle/Maven can run specific method in container template
marcphilipp Feb 11, 2025
2942940
Add documentation
marcphilipp Feb 12, 2025
eb29f16
Add to release notes
marcphilipp Feb 12, 2025
1d13d1e
Test and clarify lifecycle method executions
marcphilipp Feb 14, 2025
03da397
Move conditions to `EventConditions`
marcphilipp Feb 14, 2025
4998e02
Extract TemplateExecutor and use it for container and test templates
marcphilipp Feb 14, 2025
5948df5
Implement copying and transforming of `DynamicDescendantFilter`
marcphilipp Feb 14, 2025
bffb6c7
Allow returning a stream of context implementations
marcphilipp Feb 14, 2025
82748e9
Polishing
marcphilipp Feb 17, 2025
457cc50
Merge branch 'main' into marc/871-container-templates
marcphilipp Feb 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions documentation/src/docs/asciidoc/link-attributes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ endif::[]
:ClassOrderer_OrderAnnotation: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/ClassOrderer.OrderAnnotation.html[ClassOrderer.OrderAnnotation]
:ClassOrderer_Random: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/ClassOrderer.Random.html[ClassOrderer.Random]
:ClassOrderer: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/ClassOrderer.html[ClassOrderer]
:ContainerTemplate: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/ContainerTemplate.html[@ContainerTemplate]
:Disabled: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/Disabled.html[@Disabled]
:MethodOrderer_Alphanumeric: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/MethodOrderer.Alphanumeric.html[MethodOrderer.Alphanumeric]
:MethodOrderer_DisplayName: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/MethodOrderer.DisplayName.html[MethodOrderer.DisplayName]
Expand Down Expand Up @@ -142,6 +143,8 @@ endif::[]
:BeforeAllCallback: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/extension/BeforeAllCallback.html[BeforeAllCallback]
:BeforeEachCallback: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/extension/BeforeEachCallback.html[BeforeEachCallback]
:BeforeTestExecutionCallback: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/extension/BeforeTestExecutionCallback.html[BeforeTestExecutionCallback]
:ContainerTemplateInvocationContext: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/extension/ContainerTemplateInvocationContext.html[ContainerTemplateInvocationContext]
:ContainerTemplateInvocationContextProvider: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/extension/ContainerTemplateInvocationContextProvider.html[ContainerTemplateInvocationContextProvider]
:ExecutableInvoker: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/extension/ExecutableInvoker.html[ExecutableInvoker]
:ExecutionCondition: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/extension/ExecutionCondition.html[ExecutionCondition]
:ExtendWith: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/extension/ExtendWith.html[@ExtendWith]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ repository on GitHub.
[[release-notes-5.13.0-M1-junit-jupiter-new-features-and-improvements]]
==== New Features and Improvements

* ❓
* Introduce `@ContainerTemplate` and `ContainerTemplateInvocationContextProvider` that
allow declaring a top-level or `@Nested` test class as a template to be invoked multiple
times. This may be used, for example, to inject different parameters to be used by all
tests in the container template class or to set up each invocation of the container
template differently.


[[release-notes-5.13.0-M1-junit-vintage]]
Expand Down
40 changes: 40 additions & 0 deletions documentation/src/docs/asciidoc/user-guide/extensions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,46 @@ You may override the `getTestInstantiationExtensionContextScope(...)` method to
on the test method level.
====

[[extensions-container-templates]]
=== Providing Invocation Contexts for Container Templates

A `{ContainerTemplate}` class can only be executed when at least one
`{ContainerTemplateInvocationContextProvider}` is registered. Each such provider is
responsible for providing a `Stream` of `{ContainerTemplateInvocationContext}` instances.
Each context may specify a custom display name and a list of additional extensions that
will only be used for the next invocation of the `{ContainerTemplate}` class.

The following example shows how to write a container template as well as how to register
and implement a `{ContainerTemplateInvocationContextProvider}`.

[source,java,indent=0]
.A container template with accompanying extension
----
include::{testDir}/example/ContainerTemplateDemo.java[tags=user_guide]
----

In this example, the container template will be invoked twice, meaning all test methods in
the container template class will be executed twice. The display names of the container
invocations will be `apple` and `banana` as specified by the invocation context. Each
invocation registers a custom `{TestInstancePostProcessor}` which is used to inject a
value into a field. The output when using the `ConsoleLauncher` is as follows.

....
└─ ContainerTemplateDemo ✔
├─ apple ✔
│ ├─ notNull() ✔
│ └─ wellKnown() ✔
└─ banana ✔
├─ notNull() ✔
└─ wellKnown() ✔
....

The `{ContainerTemplateInvocationContextProvider}` extension API is primarily intended for
implementing different kinds of tests that rely on repetitive invocation of _all_ test
methods in a test class albeit in different contexts — for example, with different
parameters, by preparing the test class instance differently, or multiple times without
modifying the context.

[[extensions-test-templates]]
=== Providing Invocation Contexts for Test Templates

Expand Down
17 changes: 14 additions & 3 deletions documentation/src/docs/asciidoc/user-guide/writing-tests.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ in the `junit-jupiter-api` module.
| `@ParameterizedTest` | Denotes that a method is a <<writing-tests-parameterized-tests, parameterized test>>. Such methods are inherited unless they are overridden.
| `@RepeatedTest` | Denotes that a method is a test template for a <<writing-tests-repeated-tests, repeated test>>. Such methods are inherited unless they are overridden.
| `@TestFactory` | Denotes that a method is a test factory for <<writing-tests-dynamic-tests, dynamic tests>>. Such methods are inherited unless they are overridden.
| `@TestTemplate` | Denotes that a method is a <<writing-tests-test-templates, template for test cases>> designed to be invoked multiple times depending on the number of invocation contexts returned by the registered <<extensions-test-templates, providers>>. Such methods are inherited unless they are overridden.
| `@TestTemplate` | Denotes that a method is a <<writing-tests-test-templates, template for a test case>> designed to be invoked multiple times depending on the number of invocation contexts returned by the registered <<extensions-test-templates, providers>>. Such methods are inherited unless they are overridden.
| `@TestClassOrder` | Used to configure the <<writing-tests-test-execution-order-classes, test class execution order>> for `@Nested` test classes in the annotated test class. Such annotations are inherited.
| `@TestMethodOrder` | Used to configure the <<writing-tests-test-execution-order-methods, test method execution order>> for the annotated test class; similar to JUnit 4's `@FixMethodOrder`. Such annotations are inherited.
| `@TestInstance` | Used to configure the <<writing-tests-test-instance-lifecycle, test instance lifecycle>> for the annotated test class. Such annotations are inherited.
Expand All @@ -42,6 +42,7 @@ in the `junit-jupiter-api` module.
| `@AfterEach` | Denotes that the annotated method should be executed _after_ *each* `@Test`, `@RepeatedTest`, `@ParameterizedTest`, or `@TestFactory` method in the current class; analogous to JUnit 4's `@After`. Such methods are inherited unless they are overridden.
| `@BeforeAll` | Denotes that the annotated method should be executed _before_ *all* `@Test`, `@RepeatedTest`, `@ParameterizedTest`, and `@TestFactory` methods in the current class; analogous to JUnit 4's `@BeforeClass`. Such methods are inherited unless they are overridden and must be `static` unless the "per-class" <<writing-tests-test-instance-lifecycle, test instance lifecycle>> is used.
| `@AfterAll` | Denotes that the annotated method should be executed _after_ *all* `@Test`, `@RepeatedTest`, `@ParameterizedTest`, and `@TestFactory` methods in the current class; analogous to JUnit 4's `@AfterClass`. Such methods are inherited unless they are overridden and must be `static` unless the "per-class" <<writing-tests-test-instance-lifecycle, test instance lifecycle>> is used.
| `@ContainerTemplate` | Denotes that the annotated class is a <<writing-tests-container-templates, template for a set of test cases>> designed to be executed multiple times depending on the number of invocation contexts returned by the registered <<extensions-container-templates, providers>>.
| `@Nested` | Denotes that the annotated class is a non-static <<writing-tests-nested,nested test class>>. On Java 8 through Java 15, `@BeforeAll` and `@AfterAll` methods cannot be used directly in a `@Nested` test class unless the "per-class" <<writing-tests-test-instance-lifecycle, test instance lifecycle>> is used. Beginning with Java 16, `@BeforeAll` and `@AfterAll` methods can be declared as `static` in a `@Nested` test class with either test instance lifecycle mode. Such annotations are not inherited.
| `@Tag` | Used to declare <<writing-tests-tagging-and-filtering,tags for filtering tests>>, either at the class or method level; analogous to test groups in TestNG or Categories in JUnit 4. Such annotations are inherited at the class level but not at the method level.
| `@Disabled` | Used to <<writing-tests-disabling,disable>> a test class or test method; analogous to JUnit 4's `@Ignore`. Such annotations are not inherited.
Expand Down Expand Up @@ -2448,12 +2449,22 @@ lifecycle methods (e.g. `@BeforeEach`) and test class constructors.
include::{testDir}/example/ParameterizedTestDemo.java[tags=ParameterResolver_example]
----

[[writing-tests-container-templates]]
=== Container Templates

A `{ContainerTemplate}` class is not a regular test class but rather a template for the
contained test cases. As such, it is designed to be invoked multiple times depending on
invocation contexts returned by the registered providers. Thus, it must be used in
conjunction with a registered `{ContainerTemplateInvocationContextProvider}` extension.
Each invocation of a container template class behaves like the execution of a regular test
class with full support for the same lifecycle callbacks and extensions. Please refer to
<<extensions-container-templates>> for usage examples.

[[writing-tests-test-templates]]
=== Test Templates

A `{TestTemplate}` method is not a regular test case but rather a template for test
cases. As such, it is designed to be invoked multiple times depending on the number of
A `{TestTemplate}` method is not a regular test case but rather a template for a test
case. As such, it is designed to be invoked multiple times depending on the number of
invocation contexts returned by the registered providers. Thus, it must be used in
conjunction with a registered `{TestTemplateInvocationContextProvider}` extension. Each
invocation of a test template method behaves like the execution of a regular `@Test`
Expand Down
99 changes: 99 additions & 0 deletions documentation/src/test/java/example/ContainerTemplateDemo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright 2015-2025 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/

package example;

import static java.util.Collections.singletonList;
import static java.util.Collections.unmodifiableList;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import example.ContainerTemplateDemo.MyContainerTemplateInvocationContextProvider;

import org.junit.jupiter.api.ContainerTemplate;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ContainerTemplateInvocationContext;
import org.junit.jupiter.api.extension.ContainerTemplateInvocationContextProvider;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.Extension;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.TestInstancePostProcessor;

// tag::user_guide[]
@ContainerTemplate
@ExtendWith(MyContainerTemplateInvocationContextProvider.class)
class ContainerTemplateDemo {

static final List<String> WELL_KNOWN_FRUITS
// tag::custom_line_break[]
= unmodifiableList(Arrays.asList("apple", "banana", "lemon"));

private String fruit;

@Test
void notNull() {
assertNotNull(fruit);
}

@Test
void wellKnown() {
assertTrue(WELL_KNOWN_FRUITS.contains(fruit));
}

// end::user_guide[]
static
// tag::user_guide[]
public class MyContainerTemplateInvocationContextProvider
// tag::custom_line_break[]
implements ContainerTemplateInvocationContextProvider {

@Override
public boolean supportsContainerTemplate(ExtensionContext context) {
return true;
}

@Override
public Stream<ContainerTemplateInvocationContext>
// tag::custom_line_break[]
provideContainerTemplateInvocationContexts(ExtensionContext context) {

return Stream.of(invocationContext("apple"), invocationContext("banana"));
}

private ContainerTemplateInvocationContext invocationContext(String parameter) {
return new ContainerTemplateInvocationContext() {
@Override
public String getDisplayName(int invocationIndex) {
return parameter;
}

// end::user_guide[]
@SuppressWarnings("Convert2Lambda")
// tag::user_guide[]
@Override
public List<Extension> getAdditionalExtensions() {
return singletonList(new TestInstancePostProcessor() {
@Override
public void postProcessTestInstance(
// tag::custom_line_break[]
Object testInstance, ExtensionContext context) {
((ContainerTemplateDemo) testInstance).fruit = parameter;
}
});
}
};
}
}
}
// end::user_guide[]
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@
* executed <em>after</em> <strong>all</strong> tests in the current test class.
*
* <p>In contrast to {@link AfterEach @AfterEach} methods, {@code @AfterAll}
* methods are only executed once for a given test class.
* methods are only executed once per execution of a given test class. If the
* test class is annotated with {@link ContainerTemplate @ContainerTemplate},
* the {@code @AfterAll} methods are executed once after the last invocation of
* the container template. If a {@link Nested @Nested} test class is declared in
* a {@link ContainerTemplate @ContainerTemplate} class, its {@code @AfterAll}
* methods are called once per execution of the nested test class, namely, once
* per invocation of the outer container template.
*
* <h2>Method Signatures</h2>
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@
* executed <em>before</em> <strong>all</strong> tests in the current test class.
*
* <p>In contrast to {@link BeforeEach @BeforeEach} methods, {@code @BeforeAll}
* methods are only executed once for a given test class.
* methods are only executed once per execution of a given test class. If the
* test class is annotated with {@link ContainerTemplate @ContainerTemplate},
* the {@code @BeforeAll} methods are executed once before the first invocation
* of the container template. If a {@link Nested @Nested} test class is declared
* in a {@link ContainerTemplate @ContainerTemplate} class, its
* {@code @BeforeAll} methods are called once per execution of the nested test
* class, namely, once per invocation of the outer container template.
*
* <h2>Method Signatures</h2>
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2015-2025 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/

package org.junit.jupiter.api;

import static org.apiguardian.api.API.Status.EXPERIMENTAL;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.apiguardian.api.API;
import org.junit.platform.commons.annotation.Testable;

/**
* {@code @ContainerTemplate} is used to signal that the annotated class is a
* <em>container template</em>.
*
* <p>In contrast to regular test classes, a container template is not directly
* a test class but rather a template for a set of test cases. As such, it is
* designed to be invoked multiple times depending on the number of {@linkplain
* org.junit.jupiter.api.extension.ContainerTemplateInvocationContext invocation
* contexts} returned by the registered {@linkplain
* org.junit.jupiter.api.extension.ContainerTemplateInvocationContextProvider
* providers}. Must be used together with at least one provider. Otherwise,
* execution will fail.
*
* <p>Each invocation of a container template method behaves like the execution
* of a regular test class with full support for the same lifecycle callbacks
* and extensions.
*
* <p>{@code @ContainerTemplate} may be combined with {@link Nested @Nested} and
* a container template may contain regular nested test classes or nested
* container templates.
*
* <p>{@code @ContainerTemplate} may also be used as a meta-annotation in order
* to create a custom <em>composed annotation</em> that inherits the semantics
* of {@code @ContainerTemplate}.
*
* <h2>Inheritance</h2>
*
* <p>The {@code @ContainerTemplate} annotation is not inherited to subclasses
* but needs to be declared on each container template class individually.
*
* @since 5.13
* @see TestTemplate
* @see org.junit.jupiter.api.extension.ContainerTemplateInvocationContext
* @see org.junit.jupiter.api.extension.ContainerTemplateInvocationContextProvider
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@API(status = EXPERIMENTAL, since = "5.13")
@Testable
public @interface ContainerTemplate {
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
* <p>{@code @Nested} test classes may be ordered via
* {@link TestClassOrder @TestClassOrder} or a global {@link ClassOrderer}.
*
* <p>{@code @Nested} may be combined with
* {@link ContainerTemplate @ContainerTemplate}.
*
* <h2>Test Instance Lifecycle</h2>
*
* <ul>
Expand All @@ -42,6 +45,7 @@
* </ul>
*
* @since 5.0
* @see ContainerTemplate
* @see Test
* @see TestInstance
* @see TestClassOrder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,12 @@ enum Lifecycle {

/**
* When using this mode, a new test instance will be created once per
* test class.
* test or container template class.
*
* <p>For {@link Nested @Nested}</p> test classes declared inside an
* enclosing {@link ContainerTemplate @ContainerTemplate} test class, an
* instance of the {@code @Nested} class will be created for each
* invocation of the {@code @ContainerTemplate} test class.
*
* @see #PER_METHOD
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
*
* @since 5.0
* @see Test
* @see ContainerTemplate
* @see org.junit.jupiter.api.extension.TestTemplateInvocationContext
* @see org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider
*/
Expand Down
Loading
Loading