[[writing-tests]]
== Writing Tests

[source,java,indent=0]
.A first test case
----
include::{testDir}/example/FirstJUnit5Tests.java[tags=user_guide]
----

[[writing-tests-annotations]]
=== Annotations

JUnit Jupiter supports the following annotations for configuring tests and extending the
framework.

All core annotations are located in the `{api-package}` package in the `junit-jupiter-api`
module.

[cols="20,80"]
|===
| Annotation           | Description

| `@Test`              | Denotes that a method is a test method. Unlike JUnit 4's `@Test` annotation, this annotation does not declare any attributes, since test extensions in JUnit Jupiter operate based on their own dedicated annotations. Such methods are _inherited_ unless they are _overridden_.
| `@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_.
| `@TestInstance`      | Used to configure the <<writing-tests-test-instance-lifecycle, test instance lifecycle>> for the annotated test class. Such annotations are _inherited_.
| `@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_.
| `@DisplayName`       | Declares a custom display name for the test class or test method. Such annotations are not _inherited_.
| `@BeforeEach`        | Denotes that the annotated method should be executed _before_ *each* `@Test`, `@RepeatedTest`, `@ParameterizedTest`, or `@TestFactory` method in the current class; analogous to JUnit 4's `@Before`. Such methods are _inherited_ unless they are _overridden_.
| `@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 _hidden_ or _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 _hidden_ or _overridden_) and must be `static` (unless the "per-class" <<writing-tests-test-instance-lifecycle, test instance lifecycle>> is used).
| `@Nested`            | Denotes that the annotated class is a nested, non-static test class. `@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. Such annotations are not _inherited_.
| `@Tag`               | Used to declare _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 _disable_ a test class or test method; analogous to JUnit 4's `@Ignore`. Such annotations are not _inherited_.
| `@ExtendWith`        | Used to register custom <<extensions,extensions>>. Such annotations are _inherited_.
|===

Methods annotated with `@Test`, `@TestTemplate`, `@RepeatedTest`, `@BeforeAll`,
`@AfterAll`, `@BeforeEach`, or `@AfterEach` annotations must not return a value.

WARNING: Some annotations may currently be _experimental_. Consult the table in
<<api-evolution-experimental-apis>> for details.

[[writing-tests-meta-annotations]]
==== Meta-Annotations and Composed Annotations

JUnit Jupiter annotations can be used as _meta-annotations_. That means that you can
define your own _composed annotation_ that will automatically _inherit_ the semantics of
its meta-annotations.

For example, instead of copying and pasting `@Tag("fast")` throughout your code base (see
<<writing-tests-tagging-and-filtering>>), you can create a custom _composed annotation_
named `@Fast` as follows. `@Fast` can then be used as a drop-in replacement for
`@Tag("fast")`.

[source,java,indent=0]
----
include::{testDir}/example/Fast.java[tags=user_guide]
----

[[writing-tests-classes-and-methods]]
=== Test Classes and Methods

A _test method_ is any instance method that is directly or meta-annotated with `@Test`,
`@RepeatedTest`, `@ParameterizedTest`, `@TestFactory`, or `@TestTemplate`. A _test class_
is any top level or static member class that contains at least one test method.

[source,java,indent=0]
.A standard test class
----
include::{testDir}/example/StandardTests.java[tags=user_guide]
----

NOTE: Neither test classes nor test methods need to be `public`.

[[writing-tests-display-names]]
=== Display Names

Test classes and test methods can declare custom display names -- with spaces, special
characters, and even emojis -- that will be displayed by test runners and test reporting.

[source,java,indent=0]
----
include::{testDir}/example/DisplayNameDemo.java[tags=user_guide]
----

[[writing-tests-assertions]]
=== Assertions

JUnit Jupiter comes with many of the assertion methods that JUnit 4 has and adds a few
that lend themselves well to being used with Java 8 lambdas. All JUnit Jupiter assertions
are `static` methods in the `{Assertions}` class.

[source,java,indent=0]
----
include::{testDir}/example/AssertionsDemo.java[tags=user_guide]
----

JUnit Jupiter also comes with a few assertion methods that lend themselves well to being
used in https://kotlinlang.org/[Kotlin]. All JUnit Jupiter Kotlin assertions are top-level
functions in the `org.junit.jupiter.api` package.

// TODO: Change to using kotlin language highlighting after switch to rouge syntax highlighter
[source,groovy,indent=0]
----
include::{kotlinTestDir}/example/AssertionsKotlinDemo.kt[tags=user_guide]
----

[[writing-tests-assertions-third-party]]
==== Third-party Assertion Libraries

Even though the assertion facilities provided by JUnit Jupiter are sufficient for many
testing scenarios, there are times when more power and additional functionality such as
_matchers_ are desired or required. In such cases, the JUnit team recommends the use of
third-party assertion libraries such as {AssertJ}, {Hamcrest}, {Truth}, etc. Developers
are therefore free to use the assertion library of their choice.

For example, the combination of _matchers_ and a fluent API can be used to make
assertions more descriptive and readable. However, JUnit Jupiter's `{Assertions}` class
does not provide an
http://junit.org/junit4/javadoc/latest/org/junit/Assert.html#assertThat[`assertThat()`]
method like the one found in JUnit 4's `org.junit.Assert` class which accepts a Hamcrest
http://junit.org/junit4/javadoc/latest/org/hamcrest/Matcher.html[`Matcher`]. Instead,
developers are encouraged to use the built-in support for matchers provided by third-party
assertion libraries.

The following example demonstrates how to use the `assertThat()` support from Hamcrest in
a JUnit Jupiter test. As long as the Hamcrest library has been added to the classpath,
you can statically import methods such as `assertThat()`, `is()`, and `equalTo()` and
then use them in tests like in the `assertWithHamcrestMatcher()` method below.

[source,java,indent=0]
----
include::{testDir}/example/HamcrestAssertionDemo.java[tags=user_guide]
----

Naturally, legacy tests based on the JUnit 4 programming model can continue using
`org.junit.Assert#assertThat`.

[[writing-tests-assumptions]]
=== Assumptions

JUnit Jupiter comes with a subset of the assumption methods that JUnit 4 provides and
adds a few that lend themselves well to being used with Java 8 lambdas. All JUnit Jupiter
assumptions are static methods in the `{Assumptions}` class.

[source,java,indent=0]
----
include::{testDir}/example/AssumptionsDemo.java[tags=user_guide]
----

[[writing-tests-disabling]]
=== Disabling Tests

Entire test classes or individual test methods may be _disabled_ via the `{Disabled}`
annotation, via one of the annotations discussed in
<<writing-tests-conditional-execution>>, or via a custom <<extensions-conditions,
`ExecutionCondition`>>.

Here's a `@Disabled` test class.

[source,java,indent=0]
----
include::{testDir}/example/DisabledClassDemo.java[tags=user_guide]
----

And here's a test class that contains a `@Disabled` test method.

[source,java,indent=0]
----
include::{testDir}/example/DisabledTestsDemo.java[tags=user_guide]
----

[[writing-tests-conditional-execution]]
=== Conditional Test Execution

The <<extensions-conditions, `ExecutionCondition`>> extension API in JUnit Jupiter allows
developers to either _enable_ or _disable_ a container or test based on certain
conditions _programmatically_. The simplest example of such a condition is the built-in
`{DisabledCondition}` which supports the `{Disabled}` annotation (see
<<writing-tests-disabling>>). In addition to `@Disabled`, JUnit Jupiter also supports
several other annotation-based conditions in the `org.junit.jupiter.api.condition`
package that allow developers to enable or disable containers and tests _declaratively_.
See the following sections for details.

[TIP]
.Composed Annotations
====
Note that any of the _conditional_ annotations listed in the following sections may also
be used as a meta-annotation in order to create a custom _composed annotation_. For
example, the `@TestOnMac` annotation in the
<<writing-tests-conditional-execution-os-demo, @EnabledOnOs demo>> shows how you can
combine `@Test` and `@EnabledOnOs` in a single, reusable annotation.
====

[WARNING]
====
Each of the _conditional_ annotations listed in the following sections can only be
declared once on a given test interface, test class, or test method. If a conditional
annotation is directly present, indirectly present, or meta-present multiple times on a
given element, only the first such annotation discovered by JUnit will be used; any
additional declarations will be silently ignored. Note, however, that each conditional
annotation may be used in conjunction with other conditional annotations in the
`org.junit.jupiter.api.condition` package.
====

[[writing-tests-conditional-execution-os]]
==== Operating System Conditions

A container or test may be enabled or disabled on a particular operating system via the
`{EnabledOnOs}` and `{DisabledOnOs}` annotations.

[[writing-tests-conditional-execution-os-demo]]
[source,java,indent=0]
----
include::{testDir}/example/ConditionalTestExecutionDemo.java[tags=user_guide_os]
----

[[writing-tests-conditional-execution-jre]]
==== Java Runtime Environment Conditions

A container or test may be enabled or disabled on a particular version of the Java
Runtime Environment (JRE) via the `{EnabledOnJre}` and `{DisabledOnJre}` annotations.

[source,java,indent=0]
----
include::{testDir}/example/ConditionalTestExecutionDemo.java[tags=user_guide_jre]
----

[[writing-tests-conditional-execution-system-properties]]
==== System Property Conditions

A container or test may be enabled or disabled based on the value of the `named` JVM
system property via the `{EnabledIfSystemProperty}` and `{DisabledIfSystemProperty}`
annotations. The value supplied via the `matches` attribute will be interpreted as a
regular expression.

[source,java,indent=0]
----
include::{testDir}/example/ConditionalTestExecutionDemo.java[tags=user_guide_system_property]
----

[[writing-tests-conditional-execution-environment-variables]]
==== Environment Variable Conditions

A container or test may be enabled or disabled based on the value of the `named`
environment variable from the underlying operating system via the
`{EnabledIfEnvironmentVariable}` and `{DisabledIfEnvironmentVariable}` annotations. The
value supplied via the `matches` attribute will be interpreted as a regular expression.

[source,java,indent=0]
----
include::{testDir}/example/ConditionalTestExecutionDemo.java[tags=user_guide_environment_variable]
----

[[writing-tests-conditional-execution-scripts]]
==== Script-based Conditions

JUnit Jupiter provides the ability to either _enable_ or _disable_ a container or test
depending on the evaluation of a script configured via the `{EnabledIf}` or
`{DisabledIf}` annotation. Scripts can be written in JavaScript, Groovy, or any other
scripting language for which there is support for the Java Scripting API, defined by JSR
223.

WARNING: Conditional test execution via `{EnabledIf}` and `{DisabledIf}` is currently an
_experimental_ feature. Consult the table in <<api-evolution-experimental-apis>> for
details.

TIP: If the logic of your script depends only on the current operating system, the
current Java Runtime Environment version, a particular JVM system property, or a
particular environment variable, you should consider using one of the built-in
annotations dedicated to that purpose. See the previous sections of this chapter for
further details.

NOTE: If you find yourself using the same script-based condition many times, consider
writing a dedicated <<extensions-conditions, ExecutionCondition>> extension in order to
implement the condition in a faster, type-safe, and more maintainable manner.

[source,java,indent=0]
----
include::{testDir}/example/ConditionalTestExecutionDemo.java[tags=user_guide_scripts]
----

[[writing-tests-conditional-execution-scripts-bindings]]
===== Script Bindings

The following names are bound to each script context and therefore usable within the
script. An _accessor_ provides access to a map-like structure via a simple `String
get(String name)` method.

[cols="25,25,75"]
|===
| Name                          | Type          | Description

| `systemEnvironment`           | _accessor_    | Operating system environment variable accessor.
| `systemProperty`              | _accessor_    | JVM system property accessor.
| `junitConfigurationParameter` | _accessor_    | Configuration parameter accessor.
| `junitDisplayName`            | `String`      | Display name of the test or container.
| `junitTags`                   | `Set<String>` | All tags assigned to the test or container.
| `junitUniqueId`               | `String`      | Unique ID of the test or container.
|===


[[writing-tests-tagging-and-filtering]]
=== Tagging and Filtering

Test classes and methods can be tagged via the `@Tag` annotation. Those tags can later be
used to filter <<running-tests,test discovery and execution>>.

==== Syntax Rules for Tags

* A tag must not be `null` or _blank_.
* A _trimmed_ tag must not contain whitespace.
* A _trimmed_ tag must not contain ISO control characters.
* A _trimmed_ tag must not contain any of the following _reserved characters_.
  - `,`: _comma_
  - `(`: _left parenthesis_
  - `)`: _right parenthesis_
  - `&`: _ampersand_
  - `|`: _vertical bar_
  - `!`: _exclamation point_

NOTE: In the above context, "trimmed" means that leading and trailing whitespace
characters have been removed.

[source,java,indent=0]
----
include::{testDir}/example/TaggingDemo.java[tags=user_guide]
----

[[writing-tests-test-instance-lifecycle]]
=== Test Instance Lifecycle

In order to allow individual test methods to be executed in isolation and to avoid
unexpected side effects due to mutable test instance state, JUnit creates a new instance
of each test class before executing each _test method_ (see
<<writing-tests-classes-and-methods>>). This "per-method" test instance lifecycle is the
default behavior in JUnit Jupiter and is analogous to all previous versions of JUnit.

NOTE: Please note that the test class will still be instantiated if a given _test method_
is _disabled_ via a <<writing-tests-conditional-execution,condition>> (e.g., `@Disabled`,
`@DisabledOnOs`, etc.) even when the "per-method" test instance lifecycle mode is active.

If you would prefer that JUnit Jupiter execute all test methods on the same test
instance, simply annotate your test class with `@TestInstance(Lifecycle.PER_CLASS)`. When
using this mode, a new test instance will be created once per test class. Thus, if your
test methods rely on state stored in instance variables, you may need to reset that state
in `@BeforeEach` or `@AfterEach` methods.

The "per-class" mode has some additional benefits over the default "per-method" mode.
Specifically, with the "per-class" mode it becomes possible to declare `@BeforeAll` and
`@AfterAll` on non-static methods as well as on interface `default` methods. The
"per-class" mode therefore also makes it possible to use `@BeforeAll` and `@AfterAll`
methods in `@Nested` test classes.

If you are authoring tests using the Kotlin programming language, you may also find it
easier to implement `@BeforeAll` and `@AfterAll` methods by switching to the "per-class"
test instance lifecycle mode.

[[writing-tests-test-instance-lifecycle-changing-default]]
==== Changing the Default Test Instance Lifecycle

If a test class or test interface is not annotated with `@TestInstance`, JUnit Jupiter
will use a _default_ lifecycle mode. The standard _default_ mode is `PER_METHOD`;
however, it is possible to change the _default_ for the execution of an entire test plan.
To change the default test instance lifecycle mode, simply set the
`junit.jupiter.testinstance.lifecycle.default` _configuration parameter_ to the name of
an enum constant defined in `TestInstance.Lifecycle`, ignoring case. This can be supplied
as a JVM system property, as a _configuration parameter_ in the
`LauncherDiscoveryRequest` that is passed to the `Launcher`, or via the JUnit Platform
configuration file (see <<running-tests-config-params>> for details).

For example, to set the default test instance lifecycle mode to `Lifecycle.PER_CLASS`,
you can start your JVM with the following system property.

`-Djunit.jupiter.testinstance.lifecycle.default=per_class`

Note, however, that setting the default test instance lifecycle mode via the JUnit
Platform configuration file is a more robust solution since the configuration file can be
checked into a version control system along with your project and can therefore be used
within IDEs and your build software.

To set the default test instance lifecycle mode to `Lifecycle.PER_CLASS` via the JUnit
Platform configuration file, create a file named `junit-platform.properties` in the root
of the class path (e.g., `src/test/resources`) with the following content.

`junit.jupiter.testinstance.lifecycle.default = per_class`

WARNING: Changing the _default_ test instance lifecycle mode can lead to unpredictable
results and fragile builds if not applied consistently. For example, if the build
configures "per-class" semantics as the default but tests in the IDE are executed using
"per-method" semantics, that can make it difficult to debug errors that occur on the
build server. It is therefore recommended to change the default in the JUnit Platform
configuration file instead of via a JVM system property.

[[writing-tests-nested]]
=== Nested Tests

Nested tests give the test writer more capabilities to express the relationship among
several group of tests. Here's an elaborate example.

[source,java,indent=0]
.Nested test suite for testing a stack
----
include::{testDir}/example/TestingAStackDemo.java[tags=user_guide]
----

NOTE: _Only non-static nested classes_ (i.e. _inner classes_) can serve as `@Nested` test
classes. Nesting can be arbitrarily deep, and those inner classes are considered to be
full members of the test class family with one exception: `@BeforeAll` and `@AfterAll`
methods do not work _by default_. The reason is that Java does not allow `static` members
in inner classes. However, this restriction can be circumvented by annotating a `@Nested`
test class with `@TestInstance(Lifecycle.PER_CLASS)` (see
<<writing-tests-test-instance-lifecycle>>).

[[writing-tests-dependency-injection]]
=== Dependency Injection for Constructors and Methods

In all prior JUnit versions, test constructors or methods were not allowed to have
parameters (at least not with the standard `Runner` implementations). As one of the major
changes in JUnit Jupiter, both test constructors and methods are now permitted to have
parameters. This allows for greater flexibility and enables _Dependency Injection_ for
constructors and methods.

`{ParameterResolver}` defines the API for test extensions that wish to _dynamically_
resolve parameters at runtime. If a test constructor or a `@Test`, `@TestFactory`,
`@BeforeEach`, `@AfterEach`, `@BeforeAll`, or `@AfterAll` method accepts a parameter, the
parameter must be resolved at runtime by a registered `ParameterResolver`.

There are currently three built-in resolvers that are registered automatically.

* `{TestInfoParameterResolver}`: if a method parameter is of type `{TestInfo}`, the
  `TestInfoParameterResolver` will supply an instance of `TestInfo` corresponding to the
  current test as the value for the parameter. The `TestInfo` can then be used to retrieve
  information about the current test such as the test's display name, the test class, the
  test method, or associated tags. The display name is either a technical name, such as
  the name of the test class or test method, or a custom name configured via `@DisplayName`.
+
`{TestInfo}` acts as a drop-in replacement for the `TestName` rule from JUnit 4. The
following demonstrates how to have `TestInfo` injected into a test constructor,
`@BeforeEach` method, and `@Test` method.

[source,java,indent=0]
----
include::{testDir}/example/TestInfoDemo.java[tags=user_guide]
----

* `{RepetitionInfoParameterResolver}`: if a method parameter in a `@RepeatedTest`,
  `@BeforeEach`, or `@AfterEach` method is of type `{RepetitionInfo}`, the
  `RepetitionInfoParameterResolver` will supply an instance of `RepetitionInfo`.
  `RepetitionInfo` can then be used to retrieve information about the current repetition
  and the total number of repetitions for the corresponding `@RepeatedTest`. Note,
  however, that `RepetitionInfoParameterResolver` is not registered outside the context
  of a `@RepeatedTest`. See <<writing-tests-repeated-tests-examples>>.

* `{TestReporterParameterResolver}`: if a method parameter is of type `{TestReporter}`,
  the `TestReporterParameterResolver` will supply an instance of `TestReporter`. The
  `TestReporter` can be used to publish additional data about the current test run. The
  data can be consumed through `{TestExecutionListener}.reportingEntryPublished()` and
  thus be viewed by IDEs or included in reports.
+
In JUnit Jupiter you should use `TestReporter` where you used to print information to
`stdout` or `stderr` in JUnit 4. Using `@RunWith(JUnitPlatform.class)` will even output
all reported entries to `stdout`.

[source,java,indent=0]
----
include::{testDir}/example/TestReporterDemo.java[tags=user_guide]
----

NOTE: Other parameter resolvers must be explicitly enabled by registering appropriate
<<extensions,extensions>> via `@ExtendWith`.

Check out the `{RandomParametersExtension}` for an example of a custom
`{ParameterResolver}`. While not intended to be production-ready, it demonstrates the
simplicity and expressiveness of both the extension model and the parameter resolution
process. `MyRandomParametersTest` demonstrates how to inject random values into `@Test`
methods.

[source,java,indent=0]
----
@ExtendWith(RandomParametersExtension.class)
class MyRandomParametersTest {

	@Test
	void injectsInteger(@Random int i, @Random int j) {
		assertNotEquals(i, j);
	}

	@Test
	void injectsDouble(@Random double d) {
		assertEquals(0.0, d, 1.0);
	}

}
----

For real-world use cases, check out the source code for the `{MockitoExtension}` and the
`{SpringExtension}`.

[[writing-tests-test-interfaces-and-default-methods]]
=== Test Interfaces and Default Methods

JUnit Jupiter allows `@Test`, `@RepeatedTest`, `@ParameterizedTest`, `@TestFactory`,
`@TestTemplate`, `@BeforeEach`, and `@AfterEach` to be declared on interface `default`
methods. `@BeforeAll` and `@AfterAll` can either be declared on `static` methods in a
test interface or on interface `default` methods _if_ the test interface or test class is
annotated with `@TestInstance(Lifecycle.PER_CLASS)` (see
<<writing-tests-test-instance-lifecycle>>). Here are some examples.

[source,java]
----
include::{testDir}/example/testinterface/TestLifecycleLogger.java[tags=user_guide]
----

[source,java]
----
include::{testDir}/example/testinterface/TestInterfaceDynamicTestsDemo.java[tags=user_guide]
----

`@ExtendWith` and `@Tag` can be declared on a test interface so that classes that
implement the interface automatically inherit its tags and extensions. See
<<extensions-lifecycle-callbacks-before-after-execution>> for the source code of the
<<extensions-lifecycle-callbacks-timing-extension, TimingExtension>>.

[source,java]
----
include::{testDir}/example/testinterface/TimeExecutionLogger.java[tags=user_guide]
----

In your test class you can then implement these test interfaces to have them applied.

[source,java]
----
include::{testDir}/example/testinterface/TestInterfaceDemo.java[tags=user_guide]
----

Running the `TestInterfaceDemo` results in output similar to the following:

....
:junitPlatformTest
INFO  example.TestLifecycleLogger - Before all tests
INFO  example.TestLifecycleLogger - About to execute [dynamicTestsFromCollection()]
INFO  example.TimingExtension - Method [dynamicTestsFromCollection] took 13 ms.
INFO  example.TestLifecycleLogger - Finished executing [dynamicTestsFromCollection()]
INFO  example.TestLifecycleLogger - About to execute [isEqualValue()]
INFO  example.TimingExtension - Method [isEqualValue] took 1 ms.
INFO  example.TestLifecycleLogger - Finished executing [isEqualValue()]
INFO  example.TestLifecycleLogger - After all tests

Test run finished after 190 ms
[         3 containers found      ]
[         0 containers skipped    ]
[         3 containers started    ]
[         0 containers aborted    ]
[         3 containers successful ]
[         0 containers failed     ]
[         3 tests found           ]
[         0 tests skipped         ]
[         3 tests started         ]
[         0 tests aborted         ]
[         3 tests successful      ]
[         0 tests failed          ]

BUILD SUCCESSFUL
....

Another possible application of this feature is to write tests for interface contracts.
For example, you can write tests for how implementations of `Object.equals` or
`Comparable.compareTo` should behave as follows.

[source,java]
----
include::{testDir}/example/defaultmethods/Testable.java[tags=user_guide]
----

[source,java]
----
include::{testDir}/example/defaultmethods/EqualsContract.java[tags=user_guide]
----

[source,java]
----
include::{testDir}/example/defaultmethods/ComparableContract.java[tags=user_guide]
----

In your test class you can then implement both contract interfaces thereby inheriting the
corresponding tests. Of course you'll have to implement the abstract methods.

[source,java]
----
include::{testDir}/example/defaultmethods/StringTests.java[tags=user_guide]
----

NOTE: The above tests are merely meant as examples and therefore not complete.


[[writing-tests-repeated-tests]]
=== Repeated Tests

JUnit Jupiter provides the ability to repeat a test a specified number of times simply by
annotating a method with `@RepeatedTest` and specifying the total number of repetitions
desired. Each invocation of a repeated test behaves like the execution of a regular
`@Test` method with full support for the same lifecycle callbacks and extensions.

The following example demonstrates how to declare a test named `repeatedTest()` that
will be automatically repeated 10 times.

[source,java]
----
@RepeatedTest(10)
void repeatedTest() {
	// ...
}
----

In addition to specifying the number of repetitions, a custom display name can be
configured for each repetition via the `name` attribute of the `@RepeatedTest`
annotation. Furthermore, the display name can be a pattern composed of a combination of
static text and dynamic placeholders. The following placeholders are currently supported.

- `{displayName}`: display name of the `@RepeatedTest` method
- `{currentRepetition}`: the current repetition count
- `{totalRepetitions}`: the total number of repetitions

The default display name for a given repetition is generated based on the following
pattern: `"repetition {currentRepetition} of {totalRepetitions}"`. Thus, the display
names for individual repetitions of the previous `repeatedTest()` example would be:
`repetition 1 of 10`, `repetition 2 of 10`, etc. If you would like the display name of
the `@RepeatedTest` method included in the name of each repetition, you can define your
own custom pattern or use the predefined `RepeatedTest.LONG_DISPLAY_NAME` pattern. The
latter is equal to `"{displayName} :: repetition {currentRepetition} of
{totalRepetitions}"` which results in display names for individual repetitions like
`repeatedTest() :: repetition 1 of 10`, `repeatedTest() :: repetition 2 of 10`, etc.

In order to retrieve information about the current repetition and the total number of
repetitions programmatically, a developer can choose to have an instance of
`RepetitionInfo` injected into a `@RepeatedTest`, `@BeforeEach`, or `@AfterEach` method.

[[writing-tests-repeated-tests-examples]]
==== Repeated Test Examples

The `RepeatedTestsDemo` class at the end of this section demonstrates several examples of
repeated tests.

The `repeatedTest()` method is identical to example from the previous section; whereas,
`repeatedTestWithRepetitionInfo()` demonstrates how to have an instance of
`RepetitionInfo` injected into a test to access the total number of repetitions for the
current repeated test.

The next two methods demonstrate how to include a custom `@DisplayName` for the
`@RepeatedTest` method in the display name of each repetition. `customDisplayName()`
combines a custom display name with a custom pattern and then uses `TestInfo` to verify
the format of the generated display name. `Repeat!` is the `{displayName}` which comes
from the `@DisplayName` declaration, and `1/1` comes from
`{currentRepetition}/{totalRepetitions}`. In contrast,
`customDisplayNameWithLongPattern()` uses the aforementioned predefined
`RepeatedTest.LONG_DISPLAY_NAME` pattern.

`repeatedTestInGerman()` demonstrates the ability to translate display names of repeated
tests into foreign languages -- in this case German, resulting in names for individual
repetitions such as: `Wiederholung 1 von 5`, `Wiederholung 2 von 5`, etc.

Since the `beforeEach()` method is annotated with `@BeforeEach` it will get executed
before each repetition of each repeated test. By having the `TestInfo` and
`RepetitionInfo` injected into the method, we see that it's possible to obtain
information about the currently executing repeated test. Executing `RepeatedTestsDemo`
with the `INFO` log level enabled results in the following output.

....
INFO: About to execute repetition 1 of 10 for repeatedTest
INFO: About to execute repetition 2 of 10 for repeatedTest
INFO: About to execute repetition 3 of 10 for repeatedTest
INFO: About to execute repetition 4 of 10 for repeatedTest
INFO: About to execute repetition 5 of 10 for repeatedTest
INFO: About to execute repetition 6 of 10 for repeatedTest
INFO: About to execute repetition 7 of 10 for repeatedTest
INFO: About to execute repetition 8 of 10 for repeatedTest
INFO: About to execute repetition 9 of 10 for repeatedTest
INFO: About to execute repetition 10 of 10 for repeatedTest
INFO: About to execute repetition 1 of 5 for repeatedTestWithRepetitionInfo
INFO: About to execute repetition 2 of 5 for repeatedTestWithRepetitionInfo
INFO: About to execute repetition 3 of 5 for repeatedTestWithRepetitionInfo
INFO: About to execute repetition 4 of 5 for repeatedTestWithRepetitionInfo
INFO: About to execute repetition 5 of 5 for repeatedTestWithRepetitionInfo
INFO: About to execute repetition 1 of 1 for customDisplayName
INFO: About to execute repetition 1 of 1 for customDisplayNameWithLongPattern
INFO: About to execute repetition 1 of 5 for repeatedTestInGerman
INFO: About to execute repetition 2 of 5 for repeatedTestInGerman
INFO: About to execute repetition 3 of 5 for repeatedTestInGerman
INFO: About to execute repetition 4 of 5 for repeatedTestInGerman
INFO: About to execute repetition 5 of 5 for repeatedTestInGerman
....

[source,java]
----
include::{testDir}/example/RepeatedTestsDemo.java[tags=user_guide]
----

When using the `ConsoleLauncher` with the unicode theme enabled, execution of
`RepeatedTestsDemo` results in the following output to the console.

....
├─ RepeatedTestsDemo ✔
│  ├─ repeatedTest() ✔
│  │  ├─ repetition 1 of 10 ✔
│  │  ├─ repetition 2 of 10 ✔
│  │  ├─ repetition 3 of 10 ✔
│  │  ├─ repetition 4 of 10 ✔
│  │  ├─ repetition 5 of 10 ✔
│  │  ├─ repetition 6 of 10 ✔
│  │  ├─ repetition 7 of 10 ✔
│  │  ├─ repetition 8 of 10 ✔
│  │  ├─ repetition 9 of 10 ✔
│  │  └─ repetition 10 of 10 ✔
│  ├─ repeatedTestWithRepetitionInfo(RepetitionInfo) ✔
│  │  ├─ repetition 1 of 5 ✔
│  │  ├─ repetition 2 of 5 ✔
│  │  ├─ repetition 3 of 5 ✔
│  │  ├─ repetition 4 of 5 ✔
│  │  └─ repetition 5 of 5 ✔
│  ├─ Repeat! ✔
│  │  └─ Repeat! 1/1 ✔
│  ├─ Details... ✔
│  │  └─ Details... :: repetition 1 of 1 ✔
│  └─ repeatedTestInGerman() ✔
│     ├─ Wiederholung 1 von 5 ✔
│     ├─ Wiederholung 2 von 5 ✔
│     ├─ Wiederholung 3 von 5 ✔
│     ├─ Wiederholung 4 von 5 ✔
│     └─ Wiederholung 5 von 5 ✔
....


[[writing-tests-parameterized-tests]]
=== Parameterized Tests

Parameterized tests make it possible to run a test multiple times with different
arguments. They are declared just like regular `@Test` methods but use the
`{ParameterizedTest}` annotation instead. In addition, you must declare at least one
_source_ that will provide the arguments for each invocation and then _consume_ the
arguments in the test method.

The following example demonstrates a parameterized test that uses the `@ValueSource`
annotation to specify a `String` array as the source of arguments.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=first_example]
----

When executing the above parameterized test method, each invocation will be reported
separately. For instance, the `ConsoleLauncher` will print output similar to the
following.

....
palindromes(String) ✔
├─ [1] racecar ✔
├─ [2] radar ✔
└─ [3] able was I ere I saw elba ✔
....

WARNING: Parameterized tests are currently an _experimental_ feature. Consult the table
in <<api-evolution-experimental-apis>> for details.

[[writing-tests-parameterized-tests-setup]]
==== Required Setup

In order to use parameterized tests you need to add a dependency on the
`junit-jupiter-params` artifact. Please refer to <<dependency-metadata>> for details.

[[writing-tests-parameterized-tests-consuming-arguments]]
==== Consuming Arguments

Parameterized test methods typically _consume_ arguments directly from the configured
source (see <<writing-tests-parameterized-tests-sources>>) following a one-to-one
correlation between argument source index and method parameter index (see examples in
<<writing-tests-parameterized-tests-sources-CsvSource>>). However, a parameterized test
method may also choose to _aggregate_ arguments from the source into a single object
passed to the method (see <<writing-tests-parameterized-tests-argument-aggregation>>).
Additional arguments may also be provided by a `ParameterResolver` (e.g., to obtain an
instance of `TestInfo`, `TestReporter`, etc.). Specifically, a parameterized test method
must declare formal parameters according to the following rules.

* Zero or more _indexed arguments_ must be declared first.
* Zero or more _aggregators_ must be declared next.
* Zero or more arguments supplied by a `ParameterResolver` must be declared last.

In this context, an _indexed argument_ is an argument for a given index in the
`Arguments` provided by an `ArgumentsProvider` that is passed as an argument to the
parameterized method at the same index in the method's formal parameter list. An
_aggregator_ is any parameter of type `ArgumentsAccessor` or any parameter annotated with
`@AggregateWith`.

[[writing-tests-parameterized-tests-sources]]
==== Sources of Arguments

Out of the box, JUnit Jupiter provides quite a few _source_ annotations. Each of the
following subsections provides a brief overview and an example for each of them. Please
refer to the JavaDoc in the `{params-provider-package}` package for additional
information.

[[writing-tests-parameterized-tests-sources-ValueSource]]
===== @ValueSource

`@ValueSource` is one of the simplest possible sources. It lets you specify a single
array of literal values and can only be used for providing a single argument per
parameterized test invocation.

The following types of literal values are supported by `@ValueSource`.

- `short`
- `byte`
- `int`
- `long`
- `float`
- `double`
- `char`
- `java.lang.String`
- `java.lang.Class`

For example, the following `@ParameterizedTest` method will be invoked three times, with
the values `1`, `2`, and `3` respectively.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=ValueSource_example]
----

[[writing-tests-parameterized-tests-sources-EnumSource]]
===== @EnumSource

`@EnumSource` provides a convenient way to use `Enum` constants. The annotation provides
an optional `names` parameter that lets you specify which constants shall be used. If
omitted, all constants will be used like in the following example.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=EnumSource_example]
----

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=EnumSource_include_example]
----

The `@EnumSource` annotation also provides an optional `mode` parameter that enables
fine-grained control over which constants are passed to the test method. For example, you
can exclude names from the enum constant pool or specify regular expressions as in the
following examples.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=EnumSource_exclude_example]
----

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=EnumSource_regex_example]
----

[[writing-tests-parameterized-tests-sources-MethodSource]]
===== @MethodSource

`{MethodSource}` allows you to refer to one or more _factory_ methods of the test class
or external classes.

Factory methods within the test class must be `static` unless the test class is annotated
with `@TestInstance(Lifecycle.PER_CLASS)`; whereas, factory methods in external classes
must always be `static`. In addition, such factory methods must not accept any arguments.

Each factory method must generate a _stream_ of _arguments_, and each set of arguments
within the stream will be provided as the physical arguments for individual invocations
of the annotated `@ParameterizedTest` method. Generally speaking this translates to a
`Stream` of `Arguments` (i.e., `Stream<Arguments>`); however, the actual concrete return
type can take on many forms. In this context, a "stream" is anything that JUnit can
reliably convert into a `Stream`, such as `Stream`, `DoubleStream`, `LongStream`,
`IntStream`, `Collection`, `Iterator`, `Iterable`, an array of objects, or an array of
primitives. The "arguments" within the stream can be supplied as an instance of
`Arguments`, an array of objects (e.g., `Object[]`), or a single value if the
parameterized test method accepts a single argument.

If you only need a single parameter, you can return a `Stream` of instances of the
parameter type as demonstrated in the following example.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=simple_MethodSource_example]
----

If you do not explicitly provide a factory method name via `@MethodSource`, JUnit Jupiter
will search for a _factory_ method that has the same name as the current
`@ParameterizedTest` method by convention. This is demonstrated in the following example.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=simple_MethodSource_without_value_example]
----

Streams for primitive types (`DoubleStream`, `IntStream`, and `LongStream`) are also
supported as demonstrated by the following example.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=primitive_MethodSource_example]
----

If a parameterized test method declares multiple parameters, you need to return a
collection, stream, or array of `Arguments` instances or object arrays as shown below
(see the JavaDoc for `{MethodSource}` for further details on supported return types).
Note that `arguments(Object...)` is a static factory method defined in the `Arguments`
interface. In addition, `Arguments.of(Object...)` may be used as an alternative to
`arguments(Object...)`.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=multi_arg_MethodSource_example]
----

An external, `static` _factory_ method can be referenced by providing its _fully
qualified method name_ as demonstrated in the following example.

[source,java,indent=0]
----
package example;

include::{testDir}/example/ExternalMethodSourceDemo.java[tags=external_MethodSource_example]
----

[[writing-tests-parameterized-tests-sources-CsvSource]]
===== @CsvSource

`@CsvSource` allows you to express argument lists as comma-separated values (i.e.,
`String` literals).

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=CsvSource_example]
----

`@CsvSource` uses a single quote `'` as its quote character. See the `'baz, qux'` value
in the example above and in the table below. An empty, quoted value `''` results in an
empty `String`; whereas, an entirely _empty_ value is interpreted as a `null` reference.
An `ArgumentConversionException` is raised if the target type of a `null` reference is a
primitive type.

[cols="50,50"]
|===
| Example Input                        | Resulting Argument List

| `@CsvSource({ "foo, bar" })`         | `"foo"`, `"bar"`
| `@CsvSource({ "foo, 'baz, qux'" })`  | `"foo"`, `"baz, qux"`
| `@CsvSource({ "foo, ''" })`          | `"foo"`, `""`
| `@CsvSource({ "foo, " })`            | `"foo"`, `null`
|===

[[writing-tests-parameterized-tests-sources-CsvFileSource]]
===== @CsvFileSource

`@CsvFileSource` lets you use CSV files from the classpath. Each line from a CSV file
results in one invocation of the parameterized test.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=CsvFileSource_example]
----

[source,csv,indent=0]
.two-column.csv
----
include::{testResourcesDir}/two-column.csv[]
----

NOTE: In contrast to the syntax used in `@CsvSource`, `@CsvFileSource` uses a double
quote `"` as the quote character. See the `"United States of America"` value in the
example above. An empty, quoted value `""` results in an empty `String`; whereas, an
entirely _empty_ value is interpreted as a `null` reference. An
`ArgumentConversionException` is raised if the target type of a `null` reference is a
primitive type.

[[writing-tests-parameterized-tests-sources-ArgumentsSource]]
===== @ArgumentsSource

`@ArgumentsSource` can be used to specify a custom, reusable `ArgumentsProvider`. Note
that an implementation of `ArgumentsProvider` must be declared as either a top-level
class or as a `static` nested class.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=ArgumentsSource_example]
----

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=ArgumentsProvider_example]
----


[[writing-tests-parameterized-tests-argument-conversion]]
==== Argument Conversion

[[writing-tests-parameterized-tests-argument-conversion-widening]]
===== Widening Conversion

JUnit Jupiter supports
https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.2[Widening Primitive
Conversion] for arguments supplied to a `@ParameterizedTest`. For example, a
parameterized test annotated with `@ValueSource(ints = { 1, 2, 3 })` can be declared to
accept not only an argument of type `int` but also an argument of type `long`, `float`,
or `double`.

[[writing-tests-parameterized-tests-argument-conversion-implicit]]
===== Implicit Conversion

To support use cases like `@CsvSource`, JUnit Jupiter provides a number of built-in
implicit type converters. The conversion process depends on the declared type of each
method parameter.

For example, if a `@ParameterizedTest` declares a parameter of type `TimeUnit` and the
actual type supplied by the declared source is a `String`, the string will be
automatically converted into the corresponding `TimeUnit` enum constant.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=implicit_conversion_example]
----

`String` instances are currently implicitly converted to the following target types.

[[writing-tests-parameterized-tests-argument-conversion-implicit-table]]
[cols="10,90"]
|===
| Target Type | Example

| `boolean`/`Boolean`        | `"true"`                                 -> `true`
| `byte`/`Byte`              | `"1"`                                    -> `(byte) 1`
| `char`/`Character`         | `"o"`                                    -> `'o'`
| `short`/`Short`            | `"1"`                                    -> `(short) 1`
| `int`/`Integer`            | `"1"`                                    -> `1`
| `long`/`Long`              | `"1"`                                    -> `1L`
| `float`/`Float`            | `"1.0"`                                  -> `1.0f`
| `double`/`Double`          | `"1.0"`                                  -> `1.0d`
| `Enum` subclass            | `"SECONDS"`                              -> `TimeUnit.SECONDS`
| `java.io.File`             | `"/path/to/file"`                        -> `new File("/path/to/file")`
| `java.lang.Class`          | `"java.lang.Integer"`                    -> `java.lang.Integer.class` _(use `$` for nested classes, e.g. `"java.lang.Thread$State"`)_
| `java.lang.Class`          | `"byte"`                                 -> `byte.class` _(primitive types are supported)_
| `java.lang.Class`          | `"char[]"`                               -> `char[].class` _(array types are supported)_
| `java.math.BigDecimal`     | `"123.456e789"`                          -> `new BigDecimal("123.456e789")`
| `java.math.BigInteger`     | `"1234567890123456789"`                  -> `new BigInteger("1234567890123456789")`
| `java.net.URI`             | `"http://junit.org/"`                    -> `URI.create("http://junit.org/")`
| `java.net.URL`             | `"http://junit.org/"`                    -> `new URL("http://junit.org/")`
| `java.nio.charset.Charset` | `"UTF-8"`                                -> `Charset.forName("UTF-8")`
| `java.nio.file.Path`       | `"/path/to/file"`                        -> `Paths.get("/path/to/file")`
| `java.time.Instant`        | `"1970-01-01T00:00:00Z"`                 -> `Instant.ofEpochMilli(0)`
| `java.time.LocalDateTime`  | `"2017-03-14T12:34:56.789"`              -> `LocalDateTime.of(2017, 3, 14, 12, 34, 56, 789_000_000)`
| `java.time.LocalDate`      | `"2017-03-14"`                           -> `LocalDate.of(2017, 3, 14)`
| `java.time.LocalTime`      | `"12:34:56.789"`                         -> `LocalTime.of(12, 34, 56, 789_000_000)`
| `java.time.OffsetDateTime` | `"2017-03-14T12:34:56.789Z"`             -> `OffsetDateTime.of(2017, 3, 14, 12, 34, 56, 789_000_000, ZoneOffset.UTC)`
| `java.time.OffsetTime`     | `"12:34:56.789Z"`                        -> `OffsetTime.of(12, 34, 56, 789_000_000, ZoneOffset.UTC)`
| `java.time.YearMonth`      | `"2017-03"`                              -> `YearMonth.of(2017, 3)`
| `java.time.Year`           | `"2017"`                                 -> `Year.of(2017)`
| `java.time.ZonedDateTime`  | `"2017-03-14T12:34:56.789Z"`             -> `ZonedDateTime.of(2017, 3, 14, 12, 34, 56, 789_000_000, ZoneOffset.UTC)`
| `java.util.Currency`       | `"JPY"`                                  -> `Currency.getInstance("JPY")`
| `java.util.Locale`         | `"en"`                                   -> `new Locale("en")`
| `java.util.UUID`           | `"d043e930-7b3b-48e3-bdbe-5a3ccfb833db"` -> `UUID.fromString("d043e930-7b3b-48e3-bdbe-5a3ccfb833db")`
|===

[[writing-tests-parameterized-tests-argument-conversion-implicit-fallback]]
====== Fallback String-to-Object Conversion

In addition to implicit conversion from strings to the target types listed in the above
table, JUnit Jupiter also provides a fallback mechanism for automatic conversion from a
`String` to a given target type if the target type declares exactly one suitable _factory
method_ or a _factory constructor_ as defined below.

- __factory method__: a non-private, `static` method declared in the target type that
  accepts a single `String` argument and returns an instance of the target type. The name
  of the method can be arbitrary and need not follow any particular convention.
- __factory constructor__: a non-private constructor in the target type that accepts a
  single `String` argument. Note that the target type must be declared as either a
  top-level class or as a `static` nested class.

NOTE: If multiple _factory methods_ are discovered, they will be ignored. If a _factory
method_ and a _factory constructor_ are discovered, the factory method will be used
instead of the constructor.

For example, in the following `@ParameterizedTest` method, the `Book` argument will be
created by invoking the `Book.fromTitle(String)` factory method and passing `"42 Cats"`
as the title of the book.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=implicit_fallback_conversion_example]
----

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=implicit_fallback_conversion_example_Book]
----

[[writing-tests-parameterized-tests-argument-conversion-explicit]]
===== Explicit Conversion

Instead of relying on implicit argument conversion you may explicitly specify an
`ArgumentConverter` to use for a certain parameter using the `@ConvertWith` annotation
like in the following example. Note that an implementation of `ArgumentConverter` must be
declared as either a top-level class or as a `static` nested class.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=explicit_conversion_example]
----

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=explicit_conversion_example_ToStringArgumentConverter]
----

Explicit argument converters are meant to be implemented by test and extension authors.
Thus, `junit-jupiter-params` only provides a single explicit argument converter that may
also serve as a reference implementation: `JavaTimeArgumentConverter`. It is used via the
composed annotation `JavaTimeConversionPattern`.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=explicit_java_time_converter]
----

[[writing-tests-parameterized-tests-argument-aggregation]]
==== Argument Aggregation

By default, each _argument_ provided to a `@ParameterizedTest` method corresponds to a
single method parameter. Consequently, argument sources which are expected to supply a
large number of arguments can lead to large method signatures.

In such cases, an `{ArgumentsAccessor}` can be used instead of multiple parameters. Using
this API, you can access the provided arguments through a single argument passed to your
test method. In addition, type conversion is supported as discussed in
<<writing-tests-parameterized-tests-argument-conversion-implicit>>.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=ArgumentsAccessor_example]
----

_An instance of `ArgumentsAccessor` is automatically injected into any parameter of type
`ArgumentsAccessor`._

[[writing-tests-parameterized-tests-argument-aggregation-custom]]
===== Custom Aggregators

Apart from direct access to a `@ParameterizedTest` method's arguments using an
`ArgumentsAccessor`, JUnit Jupiter also supports the usage of custom, reusable
_aggregators_.

To use a custom aggregator simply implement the `{ArgumentsAggregator}` interface and
register it via the `@AggregateWith` annotation on a compatible parameter in the
`@ParameterizedTest` method. The result of the aggregation will then be provided as an
argument for the corresponding parameter when the parameterized test is invoked. Note
that an implementation of `ArgumentsAggregator` must be declared as either a top-level
class or as a `static` nested class.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=ArgumentsAggregator_example]
----

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=ArgumentsAggregator_example_PersonAggregator]
----

If you find yourself repeatedly declaring `@AggregateWith(MyTypeAggregator.class)` for
multiple parameterized test methods across your codebase, you may wish to create a custom
_composed annotation_ such as `@CsvToMyType` that is meta-annotated with
`@AggregateWith(MyTypeAggregator.class)`. The following example demonstrates this in
action with a custom `@CsvToPerson` annotation.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=ArgumentsAggregator_with_custom_annotation_example]
----

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=ArgumentsAggregator_with_custom_annotation_example_CsvToPerson]
----


[[writing-tests-parameterized-tests-display-names]]
==== Customizing Display Names

By default, the display name of a parameterized test invocation contains the invocation
index and the `String` representation of all arguments for that specific invocation.
However, you can customize invocation display names via the `name` attribute of the
`@ParameterizedTest` annotation like in the following example.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=custom_display_names]
----

When executing the above method using the `ConsoleLauncher` you will see output similar to the following.

....
Display name of container ✔
├─ 1 ==> first='foo', second=1 ✔
├─ 2 ==> first='bar', second=2 ✔
└─ 3 ==> first='baz, qux', second=3 ✔
....

The following placeholders are supported within custom display names.

[cols="20,80"]
|===
| Placeholder       | Description

| `{index}`         | the current invocation index (1-based)
| `{arguments}`     | the complete, comma-separated arguments list
| `{0}`, `{1}`, ... | an individual argument
|===


[[writing-tests-parameterized-tests-lifecycle-interop]]
==== Lifecycle and Interoperability

Each invocation of a parameterized test has the same lifecycle as a regular `@Test`
method. For example, `@BeforeEach` methods will be executed before each invocation.
Similar to <<writing-tests-dynamic-tests>>, invocations will appear one by one in the
test tree of an IDE. You may at will mix regular `@Test` methods and `@ParameterizedTest`
methods within the same test class.

You may use `ParameterResolver` extensions with `@ParameterizedTest` methods. However,
method parameters that are resolved by argument sources need to come first in the
argument list. Since a test class may contain regular tests as well as parameterized
tests with different parameter lists, values from argument sources are not resolved for
lifecycle methods (e.g. `@BeforeEach`) and test class constructors.

[source,java,indent=0]
----
include::{testDir}/example/ParameterizedTestDemo.java[tags=ParameterResolver_example]
----


[[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
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`
method with full support for the same lifecycle callbacks and extensions. Please refer to
<<extensions-test-templates>> for usage examples.


[[writing-tests-dynamic-tests]]
=== Dynamic Tests

The standard `@Test` annotation in JUnit Jupiter described in
<<writing-tests-annotations>> is very similar to the `@Test` annotation in JUnit 4. Both
describe methods that implement test cases. These test cases are static in the sense that
they are fully specified at compile time, and their behavior cannot be changed by
anything happening at runtime. _Assumptions provide a basic form of dynamic behavior but
are intentionally rather limited in their expressiveness._

In addition to these standard tests a completely new kind of test programming model has
been introduced in JUnit Jupiter. This new kind of test is a _dynamic test_ which is
generated at runtime by a factory method that is annotated with `@TestFactory`.

In contrast to `@Test` methods, a `@TestFactory` method is not itself a test case but
rather a factory for test cases. Thus, a dynamic test is the product of a factory.
Technically speaking, a `@TestFactory` method must return a `Stream`, `Collection`,
`Iterable`, `Iterator`, or array of `DynamicNode` instances. Instantiable subclasses of
`DynamicNode` are `DynamicContainer` and `DynamicTest`. `DynamicContainer` instances are
composed of a _display name_ and a list of dynamic child nodes, enabling the creation of
arbitrarily nested hierarchies of dynamic nodes. `DynamicTest` instances will be
executed lazily, enabling dynamic and even non-deterministic generation of test cases.

Any `Stream` returned by a `@TestFactory` will be properly closed by calling
`stream.close()`, making it safe to use a resource such as `Files.lines()`.

As with `@Test` methods, `@TestFactory` methods must not be `private` or `static` and may
optionally declare parameters to be resolved by `ParameterResolvers`.

A `DynamicTest` is a test case generated at runtime. It is composed of a _display name_
and an `Executable`. `Executable` is a `@FunctionalInterface` which means that the
implementations of dynamic tests can be provided as _lambda expressions_ or _method
references_.

.Dynamic Test Lifecycle
WARNING: The execution lifecycle of a dynamic test is quite different than it is for a
standard `@Test` case. Specifically, there are no lifecycle callbacks for individual
dynamic tests. This means that `@BeforeEach` and `@AfterEach` methods and their
corresponding extension callbacks are executed for the `@TestFactory` method but not for
each _dynamic test_. In other words, if you access fields from the test instance within a
lambda expression for a dynamic test, those fields will not be reset by callback methods
or extensions between the execution of individual dynamic tests generated by the same
`@TestFactory` method.

As of JUnit Jupiter {jupiter-version}, dynamic tests must always be created by factory
methods; however, this might be complemented by a registration facility in a later
release.

WARNING: Dynamic tests are currently an _experimental_ feature. Consult the table in
<<api-evolution-experimental-apis>> for details.

[[writing-tests-dynamic-tests-examples]]
==== Dynamic Test Examples

The following `DynamicTestsDemo` class demonstrates several examples of test factories
and dynamic tests.

The first method returns an invalid return type. Since an invalid return type cannot be
detected at compile time, a `JUnitException` is thrown when it is detected at runtime.

The next five methods are very simple examples that demonstrate the generation of a
`Collection`, `Iterable`, `Iterator`, or `Stream` of `DynamicTest` instances. Most of
these examples do not really exhibit dynamic behavior but merely demonstrate the
supported return types in principle. However, `dynamicTestsFromStream()` and
`dynamicTestsFromIntStream()` demonstrate how easy it is to generate dynamic tests for a
given set of strings or a range of input numbers.

The next method is truly dynamic in nature. `generateRandomNumberOfTests()` implements an
`Iterator` that generates random numbers, a display name generator, and a test executor
and then provides all three to `DynamicTest.stream()`. Although the non-deterministic
behavior of `generateRandomNumberOfTests()` is of course in conflict with test
repeatability and should thus be used with care, it serves to demonstrate the
expressiveness and power of dynamic tests.

The last method generates a nested hierarchy of dynamic tests utilizing
`DynamicContainer`.

[source,java]
----
include::{testDir}/example/DynamicTestsDemo.java[tags=user_guide]
----


[[writing-tests-parallel-execution]]
=== Parallel Execution

By default, JUnit Jupiter tests are run sequentially in a single thread. Running tests in
parallel, e.g. to speed up execution, is available as an opt-in feature since version 5.3.
To enable parallel execution, simply set the
`junit.jupiter.execution.parallel.enabled` configuration parameter to `true`, e.g. in `junit-platform.properties` (see <<running-tests-config-params>> for other options).

Once enabled, the JUnit Jupiter engine will execute tests on all levels of the test tree
fully in parallel according to the provided
<<writing-tests-parallel-execution-config, configuration>> while observing the declarative
<<writing-tests-parallel-execution-synchronization, synchronization>> mechanisms. Please
note that the <<running-tests-capturing-output>> feature needs to enabled separately.

WARNING: Parallel test execution is currently an _experimental_ feature. You're invited
to give it a try and provide feedback to the JUnit team so they can improve and
eventually <<api-evolution, promote>> this feature.

[[writing-tests-parallel-execution-config]]
==== Configuration

Properties like the desired parallelism and the maximum pool size can be configured using
a `{ParallelExecutionConfigurationStrategy}`. The JUnit Platform provides two
implementations out of the box: `dynamic` and `fixed`. Alternatively, you may implement a
`custom` strategy.

To select a strategy, simply set the `junit.jupiter.execution.parallel.config.strategy`
configuration parameter to one of the following options:

`dynamic`::
  Computes the desired parallelism based on the number of available processors/cores
  multiplied by the `junit.jupiter.execution.parallel.config.dynamic.factor`
  configuration parameter (defaults to `1`).

`fixed`::
  Uses the mandatory `junit.jupiter.execution.parallel.config.fixed.parallelism`
  configuration parameter as desired parallelism.

`custom`::
  Allows to specify a custom `{ParallelExecutionConfigurationStrategy}` implementation via
  the mandatory `junit.jupiter.execution.parallel.config.custom.class` configuration
  parameter to determine the desired configuration.

If no configuration strategy is set, JUnit Jupiter uses the `dynamic` configuration
strategy with a factor of 1, i.e. the desired parallelism will equal the number of
available processors/cores.

[[writing-tests-parallel-execution-synchronization]]
==== Synchronization

In the `org.junit.jupiter.api.parallel` package, JUnit Jupiter provides two
annotation-based declarative mechanisms to change the execution mode and allow for
synchronization when using shared resources in different tests.

If parallel execution is enabled, all classes and methods are executed concurrently by
default. You can change the execution mode for the annotated element and its subelements
(if any) by using the `{Execution}` annotation. The following two modes are available:

`SAME_THREAD`::
  Force execution in the same thread used by the parent. For example, when used on a test
  method, the test method will be executed in the same thread as any `@BeforeAll` or
  `@AfterAll` methods of the containing test class.

`CONCURRENT`::
  Execute concurrently unless a resource constraint forces execution in the same thread.

In addition, the `{ResourceLock}` annotation allows to declare that a test class or
method uses a specific shared resource that requires synchronized access to ensure
reliable test execution.

If the tests in the following example were run in parallel they would be flaky, i.e.
sometimes pass and other times fail, because of the inherent race condition of
writing and then reading the same system property.

[source,java]
----
include::{testDir}/example/SharedResourcesDemo.java[tags=user_guide]
----

When access to shared resources is declared using this annotation, the JUnit Jupiter
engine uses this information to ensure that no conflicting tests are run in parallel.

In addition to the string that uniquely identifies the used resource, you may specify an
access mode. Two tests that require `READ` access to a resource may run in parallel with
each other but not while any other test that requires `READ_WRITE` access is running.
