You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Unless otherwise stated, all core annotations are located in the org.junit.jupiter.api package in the junit-jupiter-api module
@Test: Denotes that a method is a test method
@ParameterizedTest: Denotes that a method is a parameterized test
@RepeatedTest: Denotes that a method is a test template for a repeated test
@TestFactory: Denotes that a method is a test factory for dynamic tests
@TestTemplate: Denotes that a method is a template for test cases designed to be invoked multiple times depending on the number of invocation contexts returned by the registered providers
@TestMethodOrder: Used to configure the test method execution order for the annotated test class; similar to JUnit 4's @FixMethodOrder
@TestInstance: Used to configure the test instance lifecycle for the annotated test class
@DisplayName: Declares a custom display name for the test class or test method
@DisplayNameGeneration: Declares a custom display name generator for the test class
@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
@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
@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; must be static (unless the "per-class" 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; must be static (unless the "per-class" test instance lifecycle is used
@Nested: Denotes that the annotated class is a non-static nested test class; @BeforeAll and @AfterAll methods cannot be used directly in a @Nested test class unless the "per-class" test instance lifecycle is used
@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
@Disabled: Used to disable a test class or test method; analogous to JUnit 4's @Ignore
@Timeout: Used to fail a test, test factory, test template, or lifecycle method if its execution exceeds a given duration
@ExtendWith: Used to register extensions declaratively
@RegisterExtension: Used to register extensions programmatically via fields
@TempDir: Used to supply a temporary directory via field injection or parameter injection in a lifecycle method or test method; located in the org.junit.jupiter.api.io package
Meta-Annotations and Composed Annotations
You can define your own composed annotation that will automatically inherit the semantics of its meta-annotations
Test Class: any top-level class, static member class, or @Nested class that contains at least one test method; test classes must not be abstract and must have a single constructor
Test Method: any instance method that is directly annotated or meta-annotated with @Test, @RepeatedTest, @ParameterizedTest, @TestFactory, or @TestTemplate
Lifecycle Method: any method that is directly annotated or meta-annotated with @BeforeAll, @AfterAll, @BeforeEach, or @AfterEach
Test methods and lifecycle methods may be declared locally within the current test class, inherited from superclasses, or inherited from interfaces
must not be abstract and must not return a value
Test classes, test methods, and lifecycle methods are not required to be public, but they must not be private
You can use the junit.jupiter.displayname.generator.default configuration parameter (e.g., in src/test/resources/junit-platform.properties) to specify the fully qualified class name of the DisplayNameGenerator you would like to use by default, e.g.,
when more power and additional functionality such as matchers are desired or required
e.g., for a combination of matchers and a fluent API to make assertions more descriptive and readable
use the built-in support for matchers provided by third-party assertion libraries such as AssertJ, Hamcrest, Truth, etc
e.g., 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
Assumptions
Assumptions is a collection of utility methods that support conditional test execution based on assumptions
Entire test classes or individual test methods may be disabled via the @Disabled annotation
Other annotation-based conditions in the org.junit.jupiter.api.condition package allow developers to enable or disable containers and tests declaratively
operating system conditions: @EnabledOnOs and @DisabledOnOs
Java Runtime Environment conditions: @EnabledOnJre and @DisabledOnJre, @EnabledForJreRange and @DisabledForJreRange
JVM system property conditions: @EnabledIfSystemProperty and @DisabledIfSystemProperty
environment variable conditions: @EnabledIfEnvironmentVariable and @DisabledIfEnvironmentVariable
Tagging
Test classes and methods can be tagged via the @Tag annotation
Tags can later be used to filter test discovery and execution
Syntax rules for tags:
must not be null or blank
must not contain whitespace
must not contain ISO control characters
must not contain any of the following reserved characters:
By default, test methods are ordered using an algorithm that is deterministic but intentionally non-obvious
Although 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
when writing integration tests or functional tests where the sequence of the tests is important
in conjunction with @TestInstance(Lifecycle.PER_CLASS)
To control the order in which test methods are executed
annotate your test class or test interface with @TestMethodOrder
specify the desired MethodOrderer implementation
implement your own custom MethodOrderer
Alphanumeric: sorts test methods alphanumerically based on their names and formal parameter lists
OrderAnnotation: sorts test methods numerically based on values specified via the @Order annotation
Random: orders test methods pseudo-randomly and supports configuration of a custom seed
JUnit creates a new instance of each test class before executing each test method
to allow individual test methods to be executed in isolation
to avoid unexpected side effects due to mutable test instance state
i.e., the default mode is Lifecycle.PER_METHOD
To execute all test methods on the same test instance
annotate test class with @TestInstance(Lifecycle.PER_CLASS)
a new test instance will be created once per test class
if your test methods rely on state stored in instance variables, you may need to reset that state in @BeforeEach or @AfterEach methods
some benefits over the default "per-method" mode:
possible to declare @BeforeAll and @AfterAll on non-static methods as well as on interface default methods
possible to use @BeforeAll and @AfterAll methods in @Nested test classes
To change the default test instance lifecycle mode for the execution of an entire test plan
set the junit.jupiter.testinstance.lifecycle.default configuration parameter to the name of an enum constant defined in TestInstance.Lifecycle, ignoring case
the supportsParameters method is implemented behind the scenes and supports parameterized types
Test Interfaces and Default Methods
@Test, @RepeatedTest, @ParameterizedTest, @TestFactory, @TestTemplate, @BeforeEach, and @AfterEach can be declared on interface default methods
@BeforeAll and @AfterAll can be declared either 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)
Repeats a test a specified number of times by annotating a method with @RepeatedTest and specifying the total number of repetitions
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
A custom display name can be configured for each repetition via the name attribute of the @RepeatedTest annotation
display name can be a pattern composed of a combination of static text and dynamic placeholders
{displayName}: display name of the @RepeatedTest method
{currentRepetition}: the current repetition count
{totalRepetitions}: the total number of repetitions
default display name for a given repetition is generated based on: "repetition {currentRepetition} of {totalRepetitions}"
predefined RepeatedTest.LONG_DISPLAY_NAME pattern: "{displayName} :: repetition {currentRepetition} of {totalRepetitions}"
Inject an instance of RepetitionInfo into @RepeatedTest, @BeforeEach, or @AfterEach method to retrieve information about the current repetition and the total number of repetitions
Parameterized tests make it possible to run a test multiple times with different arguments
Needs dependency on the junit-jupiter-params artifact
included in the junit-jupiter artifact, otherwise add separately
Declared just like regular @Test methods but use the @ParameterizedTest annotation instead
must declare at least one source that will provide the arguments for each invocation, and then consume the arguments in the test method
Consuming Arguments
Parameterized test methods typically consume arguments directly from the configured source following a one-to-one correlation between argument source index and method parameter index (as with @CsvSource)
A parameterized test method may choose to aggregate arguments from the source into a single object passed to the method (see 'Argument Aggregation')
Additional arguments may be provided by a ParameterResolver
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.
An aggregator is any parameter of type ArgumentsAccessor or any parameter annotated with @AggregateWith
It can be useful to have null and empty values supplied to our parameterized tests
The following annotations serve as sources of null and empty values for parameterized tests that accept a single argument:
@NullSource: provides a single null argument
cannot be used for a parameter that has a primitive type
@EmptySource: provides a single empty argument
for parameters of the following types: java.lang.String, java.util.List, java.util.Set, java.util.Map, primitive arrays (e.g., int[], char[][]), object arrays (e.g., String[], Integer[][])
subtypes of the supported types are not supported
@NullAndEmptySource: a composed annotation that combines the functionality of @NullSource and @EmptySource
Supply multiple varying types of blank strings by using @ValueSource
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)
in external classes: must always be static
must not accept any arguments
Each factory method must generate a stream of arguments
stream: anything that JUnit can reliably convert into a Stream, such as Stream, DoubleStream, Collection, Iterator, Iterable, an array of objects, or an array of primitives
arguments: 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
Arguments: an abstraction that provides access to an array of objects
if you only need a single parameter, you can return a Stream of instances of the parameter type
see:
explicitLocalMethodSourceStream()
explicitLocalMethodSourceArray()
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
see testWithDefaultLocalMethodSource()
streams for primitive types (DoubleStream, IntStream, and LongStream) are also supported
see testOddIntegers()
if a parameterized test method declares multiple parameters, you need to return a collection, stream, or array of Arguments instances or object arrays
see:
multiArgArgumentsStream()
multiArgArray()
an external, static factory method can be referenced by providing its fully qualified method name
e.g., 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
Implicit Conversion
To support use cases like @CsvSource, JUnit Jupiter provides a number of built-in implicit type converters
conversion process depends on the declared type of each method parameter
String instances are implicitly converted to a number of target types
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
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
factory constructor
a non-private constructor in the target type that accepts a single String argument
the target type must be declared as either a top-level class or as a static nested class
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
JUnit Jupiter also supports the usage of reusable custom aggregators
implement the ArgumentsAggregator interface and register it via the @AggregateWith annotation on a compatible parameter in the @ParameterizedTest method
result of the aggregation will then be provided as an argument for the corresponding parameter
an implementation of ArgumentsAggregator must be declared as either a top-level class or as a static nested class
-see customArgumentsAggregator() in parameterizedtests/ArgumentAggregation.java
You can create a custom composed annotation such as @CsvToMyType that is meta-annotated with @AggregateWith(MyTypeAggregator.class)
not a test case but rather a factory for test cases
produces dynamic tests
must return a single DynamicNode or a Stream, Collection, Iterable, Iterator, or array of DynamicNode instances
(as with @Test methods) must not be private or static, and may optionally declare parameters to be resolved by ParameterResolvers (see 'Dependency Injection for Constructors and Methods')
enables dynamic and even non-deterministic generation of test cases at runtime
composed of a display name and an Executable
Executable is a @FunctionalInterface - implementations of dynamic tests can be provided as lambda expressions or method references
Any Stream returned by a @TestFactory will be properly closed by calling stream.close()
safe to use a resource such as Files.lines()
Dynamic test lifecycle
quite different than it is for a standard @Test case
no lifecycle callbacks for individual dynamic tests
@BeforeEach and @AfterEach methods and their corresponding extension callbacks are executed for the @TestFactory method but not for each dynamic test
if you access fields from the test instance within a lambda expression, those fields will not be reset by callback methods or extensions between the execution of individual dynamic tests generated by the same @TestFactory method