This version is still in development and is not considered stable yet.
For the latest stable version, please use JUnit 6.0.1!

Providing Invocation Contexts for Class Templates

A @ClassTemplate class can only be executed when at least one ClassTemplateInvocationContextProvider is registered. Each such provider is responsible for providing a Stream of ClassTemplateInvocationContext 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 @ClassTemplate.

The following example shows how to write a class template as well as how to register and implement a ClassTemplateInvocationContextProvider.

A class template with accompanying extension
@ClassTemplate
@ExtendWith(ClassTemplateDemo.MyClassTemplateInvocationContextProvider.class)
class ClassTemplateDemo {

	static final List<String> WELL_KNOWN_FRUITS
		= unmodifiableList(Arrays.asList("apple", "banana", "lemon"));

	private String fruit;

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

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

	public class MyClassTemplateInvocationContextProvider
			implements ClassTemplateInvocationContextProvider {

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

		@Override
		public Stream<ClassTemplateInvocationContext>
				provideClassTemplateInvocationContexts(ExtensionContext context) {

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

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

				@Override
				public List<Extension> getAdditionalExtensions() {
					return singletonList(new TestInstancePostProcessor() {
						@Override
						public void postProcessTestInstance(
								Object testInstance, ExtensionContext context) {
							((ClassTemplateDemo) testInstance).fruit = parameter;
						}
					});
				}
			};
		}
	}
}

In this example, the class template will be invoked twice, meaning all test methods in the class template will be executed twice. The display names of the 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.

└─ ClassTemplateDemo ✔
   ├─ apple ✔
   │  ├─ notNull() ✔
   │  └─ wellKnown() ✔
   └─ banana ✔
      ├─ notNull() ✔
      └─ wellKnown() ✔

The ClassTemplateInvocationContextProvider 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. Please refer to the implementations of Parameterized Classes which uses this extension point to provide its functionality.