Annotation Interface RegisterExtension


@Target(FIELD) @Retention(RUNTIME) @Documented @API(status=STABLE, since="5.1") public @interface RegisterExtension
@RegisterExtension is used to register an Extension via a field in a test class.

In contrast to @ExtendWith which is used to register extensions declaratively, @RegisterExtension can be used to register an extension programmatically — for example, in order to pass arguments to the extension's constructor, static factory method, or builder API.

@RegisterExtension fields must not be null (when evaluated) but may be either static or non-static.

Static Fields

If a @RegisterExtension field is static, the extension will be registered after extensions that are registered at the class level via @ExtendWith. Such static extensions are not limited in which extension APIs they can implement. Extensions registered via static fields may therefore implement class-level and instance-level extension APIs such as BeforeAllCallback, AfterAllCallback, TestInstanceFactory, TestInstancePostProcessor and TestInstancePreDestroyCallback as well as method-level extension APIs such as BeforeEachCallback, etc.

Instance Fields

If a @RegisterExtension field is non-static (i.e., an instance field), the extension will be registered after the test class has been instantiated and after all TestInstancePostProcessors have been given a chance to post-process the test instance (potentially injecting the instance of the extension to be used into the annotated field). Thus, if such an instance extension implements class-level or instance-level extension APIs such as BeforeAllCallback, AfterAllCallback, TestInstanceFactory, or TestInstancePostProcessor those APIs will not be honored. By default, an instance extension will be registered after extensions that are registered at the method level via @ExtendWith; however, if the test class is configured with @TestInstance(Lifecycle.PER_CLASS) semantics, an instance extension will be registered before extensions that are registered at the method level via @ExtendWith.

Inheritance

@RegisterExtension fields are inherited from superclasses as long as they are not hidden or overridden. Furthermore, @RegisterExtension fields from superclasses will be registered before @RegisterExtension fields in subclasses.

Registration Order

By default, if multiple extensions are registered via @RegisterExtension, they will be ordered using an algorithm that is deterministic but intentionally nonobvious. This ensures that subsequent runs of a test suite execute extensions in the same order, thereby allowing for repeatable builds. However, there are times when extensions need to be registered in an explicit order. To achieve that, you can annotate @RegisterExtension fields with @Order. Any @RegisterExtension field not annotated with @Order will be ordered using the default order value. Note that @ExtendWith fields can also be ordered with @Order, relative to @RegisterExtension fields and other @ExtendWith fields.

Example Usage

In the following example, the docs field in the test class is initialized programmatically by supplying a custom lookUpDocsDir() method to a static factory method in the DocumentationExtension. The configured DocumentationExtension will be automatically registered as an extension. In addition, test methods can access the instance of the extension via the docs field if necessary.

 class DocumentationTests {

     static Path lookUpDocsDir() {
         // return path to docs dir
     }

     @RegisterExtension
     DocumentationExtension docs =
         DocumentationExtension.forPath(lookUpDocsDir());

     @Test
     void generateDocumentation() {
         // use docs ...
     }
 }

Supported Extension APIs

Since:
5.1
See Also:
@ExtendWith, Extension, @Order