1. OverviewThe goal of this document is to provide comprehensive reference documentation for programmers writing tests, extension authors, and engine authors as well as build tool and IDE vendors. Show
1.1. What is JUnit 5?Unlike previous versions of JUnit, JUnit 5 is composed of several different modules from three different sub-projects. JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage The JUnit Platform serves as a foundation for launching testing frameworks on the JVM. It also defines the JUnit
Jupiter is the combination of the programming model and extension model for writing tests and extensions in JUnit 5. The Jupiter sub-project provides a JUnit Vintage provides a 1.2. Supported Java VersionsJUnit 5 requires Java 8 (or higher) at runtime. However, you can still test code that has been compiled with previous versions of the JDK. 1.3. Getting HelpAsk JUnit 5 related questions on Stack Overflow or chat with the community on Gitter. 1.4. Getting Started1.4.1. Downloading JUnit ArtifactsTo find out what artifacts are available for download and inclusion in your project, refer to Dependency Metadata. To set up dependency management for your build, refer to Build Support and the Example Projects. 1.4.3. Example ProjectsTo see complete, working examples of projects that you can copy and experiment with, the
2. Writing TestsThe following example provides a glimpse at the minimum requirements for writing a test in JUnit Jupiter. Subsequent sections of this chapter will provide further details on all available features. A first test case
2.1. AnnotationsJUnit Jupiter supports the following annotations for configuring tests and extending the framework. Unless otherwise stated, all core annotations are located in the
2.1.1. Meta-Annotations and Composed AnnotationsJUnit 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
The following
You can even take that one step further
by introducing a custom
JUnit automatically recognizes the following as a
2.2. Definitions2.3. Test Classes and MethodsTest methods and lifecycle methods may be declared locally within the current test class, inherited from superclasses, or inherited from interfaces (see Test Interfaces and Default Methods). In addition, test methods and
lifecycle methods must not be
The following test class demonstrates the use of A standard test class
2.4. Display NamesTest classes and test methods can declare custom display names via
2.4.1. Display Name GeneratorsJUnit Jupiter supports custom display name generators that can be configured via the Generators can be created by implementing
Note that for
2.4.2. Setting the Default Display Name GeneratorYou can use the For example, to use the
Similarly, you can specify the fully qualified name of any custom class that implements In summary, the display name for a test class or method is determined according to the following precedence rules:
2.5. AssertionsJUnit 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
2.5.1. Kotlin Assertion SupportJUnit Jupiter also comes with a few assertion methods that lend themselves well to being used in Kotlin. All JUnit Jupiter Kotlin assertions are top-level functions in the
2.5.2. Third-party Assertion LibrariesEven 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 The following example demonstrates how to use the
Naturally, legacy tests based on the JUnit 4 programming model can continue using 2.6. AssumptionsJUnit 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 lambda expressions and method references. All JUnit Jupiter assumptions are static methods in the
2.7. Disabling TestsHere’s a
And here’s a test class that contains a
2.8. Conditional Test ExecutionThe
2.8.1. Operating System and Architecture ConditionsA container or test may be enabled or disabled on a particular operating system, architecture, or combination of both via the Conditional execution based on operating system
Conditional execution based on architecture
2.8.2. Java Runtime Environment ConditionsA container or test may be enabled or disabled on particular versions of the
Java Runtime Environment (JRE) via the
2.8.3. Native Image Conditions
2.8.4. System Property ConditionsA container or test may be enabled or disabled based on the value of the
2.8.5. Environment Variable ConditionsA container or test may be enabled or disabled based on the value of the
2.8.6. Custom ConditionsAs an alternative to implementing an The following test class demonstrates how to configure a local method named
Alternatively, the condition method can be located outside the test class. In this case, it must be referenced by its fully qualified name as demonstrated in the following example.
2.9. Tagging and FilteringTest classes and methods can be tagged via the
2.10. Test Execution OrderBy default, test classes and methods will be ordered using an algorithm that is deterministic but intentionally nonobvious. This ensures that subsequent runs of a test suite execute test classes and test methods in the same order, thereby allowing for repeatable builds. 2.10.1. Method OrderAlthough true unit tests typically should not rely on the order in which they are executed, there are
times when it is necessary to enforce a specific test method execution order — for example, when writing integration tests or functional tests where the sequence of the tests is important, especially in conjunction with To control the order in which test methods are executed, annotate your test class or test interface with
The following example demonstrates how to guarantee that test methods are executed in the
order specified via the
Setting the Default Method OrdererYou can use the For example, to use the
Similarly, you can specify the fully qualified name of any custom class that implements 2.10.2. Class OrderAlthough test classes typically should not rely on the order in which they are executed, there are times when it is desirable to enforce a specific test class execution order. You may wish to execute test classes in a random order to ensure there are no accidental dependencies between test classes, or you may wish to order test classes to optimize build time as outlined in the following scenarios.
To configure test class execution order globally for the entire test suite, use the You can implement your own custom
For example, for the
The configured
To configure test class execution order locally for The following example demonstrates how to guarantee that
2.11. Test Instance LifecycleIn 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 Test 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.
If you would prefer that JUnit Jupiter execute all test methods on the same test instance, annotate your test class with 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
If you are authoring tests using the Kotlin programming language, you may also find it easier to implement 2.11.1. Changing the Default Test Instance LifecycleIf a
test class or test interface is not annotated with For example, to set the default test instance lifecycle mode to
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
2.12. Nested Tests
Nested test suite for testing a stack
When executing this example in an IDE, the test execution tree in the GUI will look similar to the following image. Executing a nested test in an IDE In this example, preconditions from outer tests are used in inner tests by
defining hierarchical lifecycle methods for the setup code. For example, The fact that setup code from outer tests is run before inner tests are executed gives you the ability to run all tests independently. You can even run inner tests alone without running the outer tests, because the setup code from the outer tests is always executed.
2.13. Dependency Injection for Constructors and MethodsIn all prior JUnit versions, test constructors or methods were not allowed to have parameters (at least not with the standard
There are currently three built-in resolvers that are registered automatically.
Check out the
When the type of the parameter to inject is the only condition for your 2.14. Test Interfaces and Default MethodsJUnit Jupiter allows
In your test class you can then implement these test interfaces to have them applied.
Running the INFO example.TestLifecycleLogger - Before all tests INFO example.TestLifecycleLogger - About to execute [dynamicTestsForPalindromes()] INFO example.TimingExtension - Method [dynamicTestsForPalindromes] took 19 ms. INFO example.TestLifecycleLogger - Finished executing [dynamicTestsForPalindromes()] 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 Another possible application of this feature is to write tests for interface contracts. For example, you can write tests for how implementations of
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.
2.15. Repeated TestsJUnit Jupiter provides the ability to repeat a test a specified number of times by annotating a method with The following example demonstrates how to declare a test named
In addition to specifying the number of repetitions, a custom display name can be configured for each repetition via the
The default display name for a given repetition is generated based on the following pattern: 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 2.15.1. Repeated Test ExamplesThe The The next two methods demonstrate how to include a custom
Since the 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
When using the ├─ 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 ✔ 2.16. Parameterized TestsParameterized tests make it possible to
run a test multiple times with different arguments. They are declared just like regular The following example demonstrates a parameterized test that uses the
When
executing the above parameterized test method, each invocation will be reported separately. For instance, the palindromes(String) ✔ ├─ [1] candidate=racecar ✔ ├─ [2] candidate=radar ✔ └─ [3] candidate=able was I ere I saw elba ✔ 2.16.1. Required SetupIn order to use parameterized tests you need to add a dependency on the 2.16.2. Consuming ArgumentsParameterized test methods typically consume arguments directly from the configured source (see
Sources of Arguments) following a one-to-one correlation between argument source index and method parameter index (see examples in @CsvSource). However, a parameterized test method may also choose to aggregate arguments from the source
into a single object passed to the method (see Argument Aggregation). Additional arguments may also be provided by a
In this context, an indexed argument is an argument for a given index in the
2.16.3. Sources of ArgumentsOut 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 @ValueSource
The following types of literal values are supported by
For example, the following
Null and Empty SourcesIn order to check corner cases and verify proper behavior of our software when it is supplied bad input, it can be useful to have
If you need to supply multiple varying types of blank strings to a parameterized test, you can achieve that using @ValueSource — for example,
You can also combine
Making use of the composed
@EnumSource
The annotation’s
The annotation provides an optional
The
@MethodSource
Factory methods within the test class must be 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 If you only need a single parameter, you can return a
If you do not explicitly provide a factory method name via
Streams for primitive types (
If a parameterized test method declares multiple parameters, you need to return a collection, stream, or array of
An external,
Factory methods can declare parameters, which will be provided by registered implementations of the
@CsvSource
The default delimiter is a comma ( By default,
Except within a quoted string, leading and trailing whitespace in a CSV column is trimmed by default. This behavior can be changed by setting the
If the programming language you are using supports text blocks — for example, Java SE 15 or higher — you can alternatively use the Using a text block, the previous example can be implemented as follows.
The generated display names for the previous example include the CSV header names. [1] FRUIT = apple, RANK = 1 [2] FRUIT = banana, RANK = 2 [3] FRUIT = lemon, lime, RANK = 0xF1 [4] FRUIT = strawberry, RANK = 700_000 In contrast to CSV records supplied via the
@CsvFileSource
The default delimiter is a comma (
two-column.csv
The following listing shows the generated display names for the first two parameterized test methods above. [1] country=Sweden, reference=1 [2] country=Poland, reference=2 [3] country=United States of America, reference=3 [4] country=France, reference=700_000 The following listing shows the generated display names for the last parameterized test method above that uses CSV header names. [1] COUNTRY = Sweden, REFERENCE = 1 [2] COUNTRY = Poland, REFERENCE = 2 [3] COUNTRY = United States of America, REFERENCE = 3 [4] COUNTRY = France, REFERENCE = 700_000 In contrast to the default syntax used in
Except within a quoted string, leading and trailing whitespace in a CSV column is trimmed by default. This behavior can be changed by setting the @ArgumentsSource
2.16.4. Argument ConversionWidening ConversionJUnit Jupiter supports Widening Primitive Conversion for arguments supplied to a Implicit ConversionTo support use cases like For
example, if a
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
For example, in the following
Explicit ConversionInstead
of relying on implicit argument conversion you may explicitly specify an
If the converter is only meant to convert one type to another, you can extend
Explicit argument
converters are meant to be implemented by test and extension authors. Thus,
2.16.5. Argument AggregationBy default, each argument provided to a In such cases, an
An instance of Custom AggregatorsApart from direct access to a To use a custom aggregator, implement the
If you find yourself repeatedly declaring
2.16.6. Customizing Display NamesBy default, the display name of a parameterized test invocation contains the invocation index and the However, you can customize invocation display names via the
When executing the above method using the Display name of container ✔ ├─ 1 ==> the rank of 'apple' is 1 ✔ ├─ 2 ==> the rank of 'banana' is 2 ✔ └─ 3 ==> the rank of 'lemon, lime' is 3 ✔ Please note that The following placeholders are supported within custom display names.
When using
A parameterized test with named arguments ✔ ├─ 1: An important file ✔ └─ 2: Another file ✔ If you’d like to set a default name pattern for all parameterized tests in your project, you can declare the
The display name for a parameterized test is determined according to the following precedence rules:
2.16.7. Lifecycle and InteroperabilityEach invocation of a parameterized test has the same lifecycle as a regular You may use
2.17. Test TemplatesA 2.18. Dynamic TestsThe standard 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 In contrast to Any As with A
As of JUnit Jupiter 5.10.0-SNAPSHOT, dynamic tests must always be created by factory methods; however, this might be complemented by a registration facility in a later release. 2.18.1. Dynamic Test ExamplesThe following The first method returns an invalid return type. Since an invalid return type cannot be detected at compile time, a The next six methods demonstrate the generation of a The next method is truly dynamic in nature. The
next method is similar to For demonstration purposes, the
2.18.2. URI Test Sources for Dynamic TestsThe JUnit Platform provides The
If the DirectorySource If the FileSource If the MethodSource If the ClassSource If the UriSource If none of the above 2.19. TimeoutsThe The following example shows how
To apply the
same timeout to all test methods within a test class and all of its Declaring If 2.19.1. Thread modeThe timeout can be applied using one of the following three thread modes: When On the contrary when When 2.19.2. Default TimeoutsThe following configuration parameters can be used to specify default timeouts for all methods of a certain category unless they or an enclosing test class is annotated with
Default timeout for all testable and lifecycle methods junit.jupiter.execution.timeout.testable.method.default Default timeout for all testable methods junit.jupiter.execution.timeout.test.method.default
Default timeout for junit.jupiter.execution.timeout.testtemplate.method.default Default timeout for junit.jupiter.execution.timeout.testfactory.method.default Default timeout for junit.jupiter.execution.timeout.lifecycle.method.default Default timeout for all lifecycle methods junit.jupiter.execution.timeout.beforeall.method.default Default timeout for junit.jupiter.execution.timeout.beforeeach.method.default Default timeout for junit.jupiter.execution.timeout.aftereach.method.default Default timeout for junit.jupiter.execution.timeout.afterall.method.default Default
timeout for More specific configuration parameters override less specific ones. For example, The values of such configuration parameters must be in the following, case-insensitive format:
2.19.3. Using @Timeout for Polling TestsWhen dealing with asynchronous code, it is common to write tests that poll while waiting for something to happen before performing any assertions. In some cases you can rewrite the logic to use a By configuring a timeout for an
asynchronous test that polls, you can ensure that the test does not execute indefinitely. The following example demonstrates how to achieve this with JUnit Jupiter’s
2.19.4. Disable @Timeout GloballyWhen stepping through your code in a debug session, a fixed timeout limit may influence the result of the test, e.g. mark the test as failed although all assertions were met. JUnit Jupiter supports the 2.20. Parallel Execution
By default, JUnit Jupiter tests are run sequentially in a single thread. Running tests in parallel — for example, to speed up execution — is available as an opt-in feature since version 5.3. To enable parallel execution, set the Please note that enabling this property is only the first step required to execute tests in parallel. If enabled, test classes and methods will still be executed sequentially by default. Whether or not a node in the test tree is executed concurrently is controlled by its execution mode. The following two modes are available.
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 CONCURRENT Execute concurrently unless a resource lock forces execution in the same thread. By default, nodes in the test tree use the Configuration parameters to execute all tests in parallel
The default execution mode is applied to all nodes of the test tree with a few notable exceptions, namely test classes that use the All nodes of the test tree that are configured with the In addition, you can configure the default execution mode for top-level classes by setting the Configuration parameters to execute top-level classes in parallel but methods in same thread
The opposite combination will run all methods within one class in parallel, but top-level classes will run sequentially: Configuration parameters to execute top-level classes sequentially but their methods in parallel
The following diagram illustrates how the execution of two top-level test classes Default execution mode configuration combinations If the 2.20.1. ConfigurationProperties such as the desired parallelism and the maximum pool size can be configured using a To select a strategy, set the
Computes the desired parallelism based on the number of available processors/cores multiplied by the fixed Uses the mandatory custom Allows you to specify a custom
If no configuration strategy is set, JUnit Jupiter uses the
Relevant propertiesThe following table lists relevant properties for configuring parallel execution. See Configuration Parameters for details on how to set such properties.
2.20.2. SynchronizationIn addition to controlling the execution mode using the If the tests in the following example were run in parallel without the use of @ResourceLock, they would be flaky. Sometimes they would pass, and at other times they would fail due to the inherent race condition of writing and then reading the same JVM System Property. When access to shared resources is declared using the
In addition to the
2.21. Built-in ExtensionsWhile the JUnit team encourages reusable extensions to be packaged and maintained in separate libraries, the JUnit Jupiter API artifact includes a few user-facing extension implementations that are considered so generally useful that users shouldn’t have to add another dependency. 2.21.1. The TempDirectory Extension
The built-in For example, the following test declares a parameter annotated with A test method that requires a temporary directory
You can inject multiple temporary directories by specifying multiple annotated parameters. A test method that requires multiple temporary directories
The following example stores a shared temporary directory in a A test class that shares a temporary directory across test methods
The The default cleanup mode is A test class with a temporary directory that doesn’t get cleaned up
3. Migrating from JUnit 4Although the JUnit Jupiter programming model and extension model do not support JUnit 4 features such as Instead, JUnit provides a gentle
migration path via a JUnit Vintage test engine which allows existing tests based on JUnit 3 and JUnit 4 to be executed using the JUnit Platform infrastructure. Since all classes and annotations specific to JUnit Jupiter reside under the 3.1. Running JUnit 4 Tests on the JUnit PlatformMake sure that the See the example projects in the 3.1.1. Categories SupportFor test classes or methods that are annotated with 3.2. Migration TipsThe following are topics that you should be aware of when migrating existing JUnit 4 tests to JUnit Jupiter.
3.3. Limited JUnit 4 Rule SupportAs stated above, JUnit Jupiter does not and will not support JUnit 4 rules natively. The JUnit team realizes, however, that many organizations, especially large ones, are likely to have large JUnit 4 code bases that make use of custom rules. To serve these organizations and enable a gradual migration path the JUnit team has decided to support a selection of JUnit 4 rules verbatim within JUnit Jupiter. This support is based on adapters and is limited to those rules that are semantically compatible to the JUnit Jupiter extension model, i.e. those that do not completely change the overall execution flow of the test. The
As in JUnit 4, Rule-annotated fields as well as methods are supported. By using these class-level extensions on a test class such This limited form of However, if you intend to develop a new extension for JUnit Jupiter please use the new extension model of JUnit Jupiter instead of the rule-based model of JUnit 4. 3.4. JUnit 4 @Ignore SupportIn order to provide a smooth migration path from JUnit 4 to JUnit Jupiter, the To use
3.5. Failure Message ArgumentsThe For instance, the
method The methods affected by this change are the following:
4. Running Tests4.1. IDE Support4.1.1. IntelliJ IDEAIntelliJ IDEA supports running tests on the JUnit Platform since version 2016.2. For details please see the
post on the IntelliJ IDEA blog. Note, however, that it is recommended to use IDEA 2017.3 or newer since these newer versions of IDEA will download the following JARs automatically based on the API version used in the project:
In order to use a different JUnit 5 version (e.g., 5.10.0-SNAPSHOT), you may need to include the corresponding versions of the Additional Gradle Dependencies
Additional Maven Dependencies
4.1.2. EclipseEclipse IDE offers support for the JUnit Platform since the Eclipse Oxygen.1a (4.7.1a) release. 4.1.3. NetBeans4.1.4. Visual Studio Code4.1.5. Other IDEsIf you are using an editor or IDE other than one of those listed in the previous sections, the JUnit team provides two alternative solutions to assist you in using JUnit 5. You can use the Console Launcher manually — for example, from the command line — or execute tests with a JUnit 4 based Runner if your IDE has built-in support for JUnit 4. 4.2. Build Support4.2.1. Gradle
Starting with version 4.6, Gradle provides native support for executing tests on the JUnit Platform. To enable it, you need to specify
Configuration ParametersThe standard Gradle
Configuring Test EnginesIn order to run any tests at all, a To configure
support for JUnit Jupiter based tests, configure a
The JUnit Platform can run JUnit 4 based tests as long as you configure a
Configuring Logging (optional)JUnit uses the Java Logging APIs in the Alternatively, it’s possible to redirect log messages to other logging frameworks such as
Log4j or Logback. To use a logging framework that provides a custom implementation of
Other logging frameworks provide different means to redirect messages logged using 4.2.2. Maven
Starting with version 2.22.0, Maven Surefire and Maven Failsafe provide native support for executing tests on the JUnit Platform. The
Configuring Test EnginesIn order to have Maven Surefire or Maven Failsafe run any tests at all, at least one To configure support for JUnit Jupiter based tests, configure
Maven Surefire and Maven Failsafe can run JUnit 4 based tests alongside Jupiter tests as long as you configure
Filtering by Test Class NamesThe Maven Surefire Plugin will scan for test classes whose fully qualified names match the following patterns.
Moreover, it will exclude all nested classes (including static member classes) by default. Note,
however, that you can override this default behavior by configuring explicit Overriding exclude rules of Maven Surefire
Filtering by TagsYou can filter tests by tags or tag expressions using the following configuration properties.
Configuration ParametersYou can set JUnit Platform
configuration parameters to influence test discovery and execution by declaring the
4.2.3. AntStarting with version The The
Basic UsageThe following example demonstrates how to configure the
The The following example demonstrates how to configure the
In the above example, the For further details on usage and
configuration options please refer to the official Ant documentation for the 4.2.4. Spring BootSpring Boot provides automatic support for managing
the version of JUnit used in your project. In addition, the If your build relies on dependency management support from Spring Boot, you should not import the If you need to override the version of a dependency used in your Spring Boot application, you have to override the exact name of the version property defined in the BOM used by the Spring Boot plugin. For example, the name of the JUnit Jupiter version property in Spring Boot is With Gradle you can override the JUnit Jupiter version by including the following in your
With Maven you can
override the JUnit Jupiter version by including the following in your
4.3. Console LauncherThe An executable
You can run the standalone
You can also run the standalone
4.3.1. OptionsUsage: ConsoleLauncher [OPTIONS] Launches the JUnit Platform for test discovery and execution. [@<filename>...] One or more argument files containing options. COMMANDS -h, --help Display help information. --list-engines List all observable test engines. SELECTORS --scan-classpath, --scan-class-path[=PATH] Scan all directories on the classpath or explicit classpath roots. Without arguments, only directories on the system classpath as well as additional classpath entries supplied via -cp (directories and JAR files) are scanned. Explicit classpath roots that are not on the classpath will be silently ignored. This option can be repeated. --scan-modules EXPERIMENTAL: Scan all resolved modules for test discovery. -u, --select-uri=URI Select a URI for test discovery. This option can be repeated. -f, --select-file=FILE Select a file for test discovery. This option can be repeated. -d, --select-directory=DIR Select a directory for test discovery. This option can be repeated. -o, --select-module=NAME EXPERIMENTAL: Select single module for test discovery. This option can be repeated. -p, --select-package=PKG Select a package for test discovery. This option can be repeated. -c, --select-class=CLASS Select a class for test discovery. This option can be repeated. -m, --select-method=NAME Select a method for test discovery. This option can be repeated. -r, --select-resource=RESOURCE Select a classpath resource for test discovery. This option can be repeated. -i, --select-iteration=TYPE:VALUE[INDEX(..INDEX)?(,INDEX(..INDEX)?)*] Select iterations for test discovery (e.g. method:com.acme.Foo#m() [1..2]). This option can be repeated. FILTERS -n, --include-classname=PATTERN Provide a regular expression to include only classes whose fully qualified names match. To avoid loading classes unnecessarily, the default pattern only includes class names that begin with "Test" or end with "Test" or "Tests". When this option is repeated, all patterns will be combined using OR semantics. Default: ^(Test.*|.+[.$]Test.*|.*Tests?)$ -N, --exclude-classname=PATTERN Provide a regular expression to exclude those classes whose fully qualified names match. When this option is repeated, all patterns will be combined using OR semantics. --include-package=PKG Provide a package to be included in the test run. This option can be repeated. --exclude-package=PKG Provide a package to be excluded from the test run. This option can be repeated. -t, --include-tag=TAG Provide a tag or tag expression to include only tests whose tags match. When this option is repeated, all patterns will be combined using OR semantics. -T, --exclude-tag=TAG Provide a tag or tag expression to exclude those tests whose tags match. When this option is repeated, all patterns will be combined using OR semantics. -e, --include-engine=ID Provide the ID of an engine to be included in the test run. This option can be repeated. -E, --exclude-engine=ID Provide the ID of an engine to be excluded from the test run. This option can be repeated. RUNTIME CONFIGURATION -cp, --classpath, --class-path=PATH Provide additional classpath entries -- for example, for adding engines and their dependencies. This option can be repeated. --config=KEY=VALUE Set a configuration parameter for test discovery and execution. This option can be repeated. REPORTING --fail-if-no-tests Fail and return exit status code 2 if no tests are found. --reports-dir=DIR Enable report output into a specified local directory (will be created if it does not exist). CONSOLE OUTPUT --disable-ansi-colors Disable ANSI colors in output (not supported by all terminals). --color-palette=FILE Specify a path to a properties file to customize ANSI style of output (not supported by all terminals). --single-color Style test output using only text attributes, no color (not supported by all terminals). --disable-banner Disable print out of the welcome message. --details=MODE Select an output details mode for when tests are executed. Use one of: none, summary, flat, tree, verbose. If 'none' is selected, then only the summary and test failures are shown. Default: tree. --details-theme=THEME Select an output details tree theme for when tests are executed. Use one of: ascii, unicode. Default is detected based on default character encoding. For more information, please refer to the JUnit User Guide at https://junit.org/junit5/docs/current/user-guide/ 4.3.2. Argument Files (@-files)On some platforms you may run into system limitations on the length of a command line when creating a command line with lots of options or with long arguments. Since version 1.3, the The arguments within a file can be separated by spaces or newlines. If an argument contains embedded whitespace, the whole argument should be wrapped in double or single quotes — for example, If the argument file does not exist or cannot be read, the argument will be treated literally and will not be removed. This will likely result in an "unmatched argument" error message. You can troubleshoot such errors by
executing the command with the Multiple @-files may be specified on the command line. The specified path may be relative to the current directory or absolute. You can pass a real parameter with an initial 4.3.3. Color customizationThe colors used in the output of the
4.4. Using JUnit 4 to run the JUnit Platform
The Annotating a class with
4.4.1. SetupYou need the following artifacts and their dependencies on the classpath. See Dependency Metadata for details regarding group IDs, artifact IDs, and versions. Explicit Dependencies
Transitive Dependencies
4.4.2. Display Names vs. Technical NamesTo define a
custom display name for the class run via By default, display names will be used for test artifacts; however, when the Note that the presence of 4.4.3. Single Test ClassOne way to use the
4.4.4. Test SuiteIf you have multiple test classes you can create a test suite as can be seen in the following example.
The
4.5. Configuration ParametersIn addition to instructing the platform which test classes and test engines to include, which packages to scan, etc., it is sometimes necessary to provide additional custom configuration parameters that are specific to a particular test engine, listener, or registered
extension. For example, the JUnit Jupiter
Configuration Parameters are text-based key-value pairs that can be supplied to test engines running on the JUnit Platform via one of the following mechanisms.
4.5.1. Pattern Matching SyntaxThis section describes the pattern matching syntax that is applied to the configuration parameters used for the following features.
If the value for the given configuration parameter consists solely of an asterisk ( Examples:
4.6. TagsTags are a JUnit Platform concept for marking and filtering tests. The programming model for adding tags to containers and tests is defined by the testing framework. For example, in JUnit Jupiter based
tests, the 4.6.1. Syntax Rules for TagsRegardless how a tag is specified, the JUnit Platform enforces the following rules:
4.6.2. Tag ExpressionsTag expressions are boolean expressions with the operators Two special expressions are supported,
If you are tagging your tests across multiple dimensions, tag expressions help you to select which tests to execute. When tagging by test type (e.g., micro, integration, end-to-end) and feature (e.g., product, catalog, shipping), the following tag expressions can be useful.
4.7. Capturing Standard Output/ErrorSince version 1.3, the JUnit Platform provides opt-in support for capturing output printed to If enabled, the JUnit Platform captures the corresponding output and publishes it as a report entry using the Please note that the captured output will only contain output emitted by the thread that was used to execute a container or test. Any output by other threads will be omitted because particularly when executing tests in parallel it would be impossible to attribute it to a specific test or container. 4.8. Using ListenersThe JUnit Platform provides the following listener APIs that allow JUnit, third parties, and custom user code to react to events fired at various points during the discovery and execution of a
The The For details on registering and configuring listeners, see the following sections of this guide.
The JUnit Platform provides the following listeners which you may wish to use with your test suite. JUnit Platform Reporting
LoggingListener
SummaryGeneratingListener
UniqueIdTrackingListener
4.8.1. Flight Recorder SupportSince version 1.7, the JUnit Platform provides opt-in support for generating Flight Recorder events. JEP 328 describes the Java Flight Recorder (JFR) as:
In order to record Flight Recorder events generated while running tests, you need to:
Please consult the manual of your build tool for the appropriate commands. To analyze the recorded events, use the jfr command line tool shipped with recent JDKs or open the recording file with JDK Mission Control.
5. Extension Model5.1. OverviewIn contrast to the competing 5.2. Registering Extensions5.2.1. Declarative Extension RegistrationDevelopers
can register one or more extensions declaratively by annotating a test interface, test class, test method, or custom composed annotation with For example, to register a
To register the
Multiple extensions can be registered together like this:
As an alternative, multiple extensions can be registered separately like this:
If you wish to combine multiple extensions in a reusable way, you can define a custom composed annotation and use
The above examples demonstrate how
5.2.2. Programmatic Extension RegistrationDevelopers can register extensions programmatically by annotating fields in test classes with When an extension is registered declaratively via
Static FieldsIf a In the following example, the Registering an extension via a static field in Java
Static Fields in Kotlin The Kotlin programming language does not have the concept of a The following example is a
version of the Registering an extension via a static field in Kotlin
Instance FieldsIf a In the following example, the An extension registered via an instance field
5.2.3. Automatic Extension RegistrationIn addition to
declarative extension registration and programmatic extension registration support using annotations, JUnit Jupiter also supports global extension registration via Java’s Specifically, a custom extension can be registered by supplying its fully qualified class name in a file named Enabling Automatic Extension DetectionAuto-detection is an
advanced feature and is therefore not enabled by default. To enable it, set the For example, to enable auto-detection of extensions, you can start your JVM with the following system property.
When auto-detection is enabled, extensions discovered via the 5.2.4. Extension InheritanceRegistered extensions are inherited within test class hierarchies with top-down semantics. Similarly, extensions registered at the class-level are inherited at the method-level. Furthermore, a specific extension implementation can only be registered once for a given extension context and its parent contexts. Consequently, any attempt to register a duplicate extension implementation will be ignored. 5.3. Conditional Test Execution
An When multiple 5.3.1. Deactivating ConditionsSometimes it can be useful to run a test suite without certain conditions being active. For example, you may wish to run tests even if they are annotated with For example, to deactivate JUnit’s
Pattern Matching Syntax5.4. Test Instance Pre-construct CallbackThis extension provides a symmetric call to 5.5. Test Instance Factories
Common use cases include acquiring the test instance from a dependency injection framework or invoking a static factory method to create the test class instance. If no Extensions that implement
5.6. Test Instance Post-processingCommon use cases include injecting dependencies into the test instance, invoking custom initialization methods on the test instance, etc. 5.7. Test Instance Pre-destroy Callback
Common use cases include cleaning dependencies that have been injected into the test instance, invoking custom de-initialization methods on the test instance, etc. 5.8. Parameter Resolution
If a test class constructor, test method, or lifecycle method (see Test
Classes and Methods) declares a parameter, the parameter must be resolved at runtime by a If you wish to implement a custom
5.9. Test Result Processing
Extensions implementing this interface can be registered at the method level or at the class level. In the latter case they will be invoked for any contained test method including those in
5.10. Test Lifecycle CallbacksThe following interfaces define the APIs for extending tests at various points in the test execution lifecycle. Consult the following sections for examples and the Javadoc for each of these interfaces in the
5.10.1. Before and After Test Execution Callbacks
The following example shows how to use these callbacks to calculate and log the execution time of a test method. An extension that times and logs the execution of test methods
Since the A test class that uses the example TimingExtension
The following is an example of the logging produced when INFO: Method [sleep20ms] took 24 ms. INFO: Method [sleep50ms] took 53 ms. 5.11. Exception HandlingExceptions thrown during the test execution may be intercepted and handled accordingly before propagating further, so that certain actions like error logging or resource releasing may be defined in specialized The following example shows an extension which will swallow all instances of An exception handling extension that filters IOExceptions in test execution
Another example shows how to record the state of an application under test exactly at the point of unexpected exception being thrown during setup and cleanup.
Note that unlike relying on lifecycle callbacks, which may or may not be executed depending on the test status, this solution guarantees execution immediately after failing An exception handling extension that records application state on error
Multiple execution exception handlers may be invoked for the same lifecycle method in order of declaration. If one of the handlers swallows the handled exception, subsequent ones will not be executed, and no failure will be propagated to JUnit engine, as if the exception was never thrown. Handlers may also choose to rethrow the exception or throw a different one, potentially wrapping the original. Extensions implementing Registering multiple exception handling extensions
5.12. Intercepting Invocations
The following example shows an extension that executes all test methods in Swing’s Event Dispatch Thread. An extension that executes tests in a user-defined thread
5.13. Providing Invocation Contexts for Test TemplatesA A test template with accompanying extension
In this example, the test template will be invoked twice. The display names of the invocations will be
└─ testTemplate(String) ✔ ├─ apple ✔ └─ banana ✔ The 5.14. Keeping State in ExtensionsUsually, an extension is instantiated only once. So the question becomes relevant: How do you keep the
state from one invocation of an extension to the next? The
5.15. Supported Utilities in ExtensionsThe 5.15.1. Annotation Support
5.15.2. Class Support
5.15.3. Reflection Support
5.15.4. Modifier Support
5.16. Relative Execution Order of User Code and ExtensionsWhen executing a test class that contains one or more test methods, a number of extension callbacks are called in addition to the user-supplied test and lifecycle methods. 5.16.1. User and Extension CodeThe following diagram illustrates the relative order of user-supplied code and extension code. User-supplied test and lifecycle methods are shown in orange, with callback code implemented by extensions shown in blue. The grey box denotes the execution of a single test method and will be repeated for every test method in the test class. User code and extension code
In the simplest case only the actual test method will be executed (step 8); all other steps are optional depending on the presence of user code or extension support for the corresponding lifecycle callback. For further details on the various lifecycle callbacks please consult the respective Javadoc for each annotation and extension. All invocations of user code methods in the above table can additionally be intercepted by implementing
5.16.2. Wrapping Behavior of CallbacksJUnit Jupiter always guarantees wrapping behavior for multiple registered extensions that implement lifecycle callbacks such
as That means that, given two extensions JUnit Jupiter also guarantees wrapping behavior within class and interface hierarchies for user-supplied lifecycle methods (see Test Classes and Methods).
The
following examples demonstrate this behavior. Please note that the examples do not actually do anything realistic. Instead, they mimic common scenarios for testing interactions with the database. All methods imported statically from the Extension1
Extension2
AbstractDatabaseTests
DatabaseTestsDemo
When the @BeforeAll AbstractDatabaseTests.createDatabase() @BeforeAll DatabaseTestsDemo.beforeAll() Extension1.beforeEach() Extension2.beforeEach() @BeforeEach AbstractDatabaseTests.connectToDatabase() @BeforeEach DatabaseTestsDemo.insertTestDataIntoDatabase() @Test DatabaseTestsDemo.testDatabaseFunctionality() @AfterEach DatabaseTestsDemo.deleteTestDataFromDatabase() @AfterEach AbstractDatabaseTests.disconnectFromDatabase() Extension2.afterEach() Extension1.afterEach() @BeforeAll DatabaseTestsDemo.afterAll() @AfterAll AbstractDatabaseTests.destroyDatabase() The following sequence diagram helps to shed further light on what actually goes on within the DatabaseTestsDemo JUnit Jupiter does not guarantee the execution order of multiple lifecycle methods that are declared within a single test class or test interface. It may at times appear that JUnit Jupiter invokes such methods in alphabetical order. However, that is not precisely true. The ordering is analogous to the
ordering for
In addition, JUnit Jupiter does not support wrapping behavior for multiple lifecycle methods declared within a single test class or test interface. The following example demonstrates this behavior. Specifically, the lifecycle method configuration is broken due to the order in which the locally declared lifecycle methods are executed.
BrokenLifecycleMethodConfigDemo
When the Extension1.beforeEach() Extension2.beforeEach() @BeforeEach BrokenLifecycleMethodConfigDemo.insertTestDataIntoDatabase() @BeforeEach BrokenLifecycleMethodConfigDemo.connectToDatabase() @Test BrokenLifecycleMethodConfigDemo.testDatabaseFunctionality() @AfterEach BrokenLifecycleMethodConfigDemo.disconnectFromDatabase() @AfterEach BrokenLifecycleMethodConfigDemo.deleteTestDataFromDatabase() Extension2.afterEach() Extension1.afterEach() The following sequence diagram helps to shed further light on what actually goes on within the BrokenLifecycleMethodConfigDemo
6. Advanced Topics6.1. JUnit Platform Reporting
6.1.1. Legacy XML format
The 6.1.2. Open Test Reporting XML format
The listener is auto-registered and can be configured via the following Configuration Parameters:
Enable/disable writing the report. junit.platform.reporting.output.dir=<path> Configure the output directory for the reports. By default, If enabled, the listener creates an XML report file named
GradleFor Gradle, writing Open Test Reporting compatible XML reports can be enabled and configured via system properties. The following samples configure its output directory to be the same directory Gradle uses for its own XML reports. A Groovy DSL
Kotlin DSL
MavenFor Maven Surefire/Failsafe, you can enable Open Test Reporting output and configure the resulting XML files to be written to the same directory Surefire/Failsafe uses for its own XML reports as follows:
Console LauncherWhen using the Console Launcher, you can enable Open Test Reporting output by setting the configuration parameters via
6.2. JUnit Platform Suite EngineThe JUnit Platform supports the declarative definition and execution of suites of tests from any test engine using the JUnit Platform. 6.2.1. SetupIn addition to the
Required Dependencies
Transitive Dependencies
6.2.2. @Suite ExampleBy annotating a class with
6.3. JUnit Platform Test KitThe 6.3.1. Engine Test KitThe
The following test class written using JUnit Jupiter will be used in subsequent examples.
For the sake of brevity, the following sections demonstrate how to test JUnit’s own 6.3.2. Asserting StatisticsOne of the most common features of the Test Kit is the ability to assert statistics against events fired during the execution of a
6.3.3. Asserting EventsIf you find that asserting statistics alone is insufficient for verifying the expected behavior of test execution, you can work directly with the recorded For example, if you want to verify the reason that the
If you want to verify the type of exception thrown from the
Although typically unnecessary, there are times when you need to verify all of the events fired during the execution of a
If you want to do a partial match with or without ordering requirements, you can use the methods
The
6.4. JUnit Platform Launcher APIOne of the prominent goals of JUnit 5 is to make the interface between JUnit and its programmatic clients – build tools and IDEs – more powerful and stable. The purpose is to decouple the internals of discovering and executing tests from all the filtering and configuration that’s necessary from the outside. JUnit 5 introduces the concept of a 6.4.1. Discovering TestsHaving test discovery as a dedicated feature of the platform itself frees IDEs and build tools from most of the difficulties they had to go through to identify test classes and test methods in previous versions of JUnit. Usage Example:
You can select classes, methods, and all classes in a package or even search for all tests in the class-path or module-path. Discovery takes place across all participating test engines. The resulting Clients can register one or more 6.4.2. Executing TestsTo execute tests, clients can use the same
6.4.3. Registering a TestEngine6.4.4. Registering a PostDiscoveryFilterIn addition to specifying post-discovery filters as part of a For example, an 6.4.5. Registering a LauncherSessionListenerRegistered implementations of Tool SupportThe following build tools and IDEs are known to provide full support for
Other tools might also work but have not been tested explicitly. Example UsageA src/test/java/example/session/GlobalSetupTeardownListener.java
This sample uses the HTTP server implementation from the jdk.httpserver module that comes with the JDK but would work similarly with any other server or resource. In order for the listener to be picked up by JUnit Platform, you need to register it as a service by adding a resource file with the following name and contents to your test runtime classpath (e.g. by adding the file to src/test/resources/META-INF/services/org.junit.platform.launcher.LauncherSessionListener
You can now use the resource from your test: src/test/java/example/session/HttpTests.java
6.4.6. Registering a LauncherDiscoveryListenerIn addition to specifying discovery listeners as part of a For example, an 6.4.7. Registering a TestExecutionListenerIn addition to the public For example, an 6.4.8. Configuring a TestExecutionListenerWhen a 6.4.9. Deactivating a TestExecutionListenerSometimes it can be useful to run a test suite without certain execution listeners being active. For example, you might have custom a
Pattern Matching Syntax6.4.10. Configuring the LauncherIf you require fine-grained control over
automatic detection and registration of test engines and listeners, you may create an instance of
6.5. Test EnginesA For example, JUnit provides a 6.5.1. JUnit Test EnginesJUnit provides three
6.5.2. Custom Test EnginesYou can contribute your own custom Every
In order to facilitate test discovery within IDEs and tools prior to launching the JUnit Platform, If your custom Although there is currently no official guide on how to implement a custom
6.5.3. Registering a TestEngine
For example, the 7. API EvolutionOne of the major goals of JUnit 5 is to improve maintainers' capabilities to evolve JUnit despite its being used in many projects. With JUnit 4 a lot of stuff that was originally added as an internal construct only got used by external extension writers and tool builders. That made changing JUnit 4 especially difficult and sometimes impossible. That’s why JUnit 5 introduces a defined lifecycle for all publicly available interfaces, classes, and methods. 7.1. API Version and StatusEvery published artifact has a version number
If the 7.2. Experimental APIsThe following table lists which APIs are currently designated as
experimental via
7.3. Deprecated APIsThe following table lists which APIs are currently designated as deprecated via
7.4. @API Tooling SupportThe @API Guardian project plans to provide tooling support for publishers and consumers of APIs annotated with @API. For
example, the tooling support will likely provide a means to check if JUnit APIs are being used in accordance with 8. Contributors9. Release NotesThe release notes are available here. 10. Appendix10.1. Reproducible BuildsStarting with version 5.7, JUnit 5 aims for its non-javadoc JARs to be reproducible. Under identical build conditions, such as Java version, repeated builds should provide the same output byte-for-byte. This means that anyone can reproduce the build conditions of the artifacts on Maven Central/Sonatype and produce the same output artifact locally, confirming that the artifacts in the repositories were actually generated from this source code. 10.2. Dependency Metadata10.2.1. JUnit Platform
10.2.2. JUnit Jupiter
10.2.3. JUnit Vintage
10.2.4. Bill of Materials (BOM)The Bill of Materials POM provided under the following Maven coordinates can be used to ease dependency management when referencing multiple of the above artifacts using Maven or Gradle.
10.2.5. DependenciesMost of the above artifacts have a dependency in their published Maven POMs on the following @API Guardian JAR.
In addition, most of the above artifacts have a direct or transitive dependency on the following OpenTest4J JAR.
10.3. Dependency DiagramWhat is JUnit Jupiter test?JUnit Jupiter is the combination of the programming model and extension model for writing tests and extensions in JUnit 5. The Jupiter sub-project provides a TestEngine for running Jupiter based tests on the platform. JUnit Vintage provides a TestEngine for running JUnit 3 and JUnit 4 based tests on the platform.
Is JUnit 5 the same as JUnit Jupiter?It's important, however, to understand that the two terms are not the same. JUnit Jupiter is the API for writing tests using JUnit version 5. JUnit 5 is the project name (and version) that includes the separation of concerns reflected in all three major modules: JUnit Jupiter, JUnit Platform, and JUnit Vintage.
How do I update my JUnit version?Add JUnit Dependency. JUnit migration.. Select new project.. New Maven project. Check Version and Spring Boot. ... . JUnit 4 test cases. Add Functional Code. ... . Running tests. Migrate JUnit 4 to JUnit 5. ... . The project explorer view. Add JUnit 5 Dependency. ... . Before and after view. Your final pom file will look like this:. What is the latest JUnit version?JUnit 5 is the latest generation of JUnit. It includes focussing on Java 8 and above with the facility of allowing various types of testing for developers on JVM. The latest release of the JUnit 5 generation is 5.7. 1 which was released in February 2021.
|