This document contains the change log for all JUnit 5 releases since 5.9 GA.
Please refer to the User Guide for comprehensive reference documentation for programmers writing tests, extension authors, and engine authors as well as build tool and IDE vendors.
5.10.3
Date of Release: June 27, 2024
Scope: Bug fixes and enhancements since 5.10.2
For a complete list of all closed issues and pull requests for this release, consult the 5.10.3 milestone page in the JUnit repository on GitHub.
JUnit Platform
Bug Fixes
-
The
junit-platform-suite-engine
now includes configuration provided via@ConfigurationParameter
when selecting tests byUniqueId
. -
In order to support using
@EnabledInNativeImage
on test classes,UniqueIdTrackingListener
now tracks descendants of skipped test containers. -
Attempting to deserialize a
TestIdentifier
no longer causes aNullPointerException
when there is no parent identifier. See issue 3819.
5.10.2
Date of Release: February 4, 2024
Scope: minor bug fixes and changes since 5.10.1.
For a complete list of all closed issues and pull requests for this release, consult the 5.10.2 milestone page in the JUnit repository on GitHub.
JUnit Platform
Bug Fixes
-
The
junit-platform-launcher
may now be used as a Java module whenjunit.platform.launcher.interceptors.enabled
is set totrue
.-
See issue #3561 for details.
-
Deprecations and Breaking Changes
-
Field predicates are no longer applied eagerly while searching the type hierarchy.
-
This reverts changes made in 5.10.1 that affected
findFields(…)
andstreamFields(…)
inReflectionSupport
as well asfindAnnotatedFields(…)
andfindAnnotatedFieldValues(…)
inAnnotationSupport
. -
See issue #3638 for details.
-
-
Method predicates are no longer applied eagerly while searching the type hierarchy.
-
This reverts changes made in 5.10.1 that affected
findMethods(…)
andstreamMethods(…)
inReflectionSupport
as well asfindAnnotatedMethods(…)
inAnnotationSupport
. -
See issue #3600 for details.
-
JUnit Jupiter
Bug Fixes
-
JUnit Jupiter once again properly detects when a
@Test
method is overridden in a subclass.-
See issue #3600 for details.
-
Deprecations and Breaking Changes
-
A package-private static field annotated with
@TempDir
is once again shadowed by a non-static field annotated with@TempDir
when the non-static field resides in a different package and has the same name as the static field.-
This reverts changes made in 5.10.1.
-
See issue #3638 for details.
-
-
A package-private class-level lifecycle method annotated with
@BeforeAll
or@AfterAll
is once again shadowed by a method-level lifecycle method annotated with@BeforeEach
or@AfterEach
when the method-level lifecycle method resides in a different package and has the same name as the class-level lifecycle method.-
This reverts changes made in 5.10.1.
-
See issue #3600 for details.
-
5.10.1
Date of Release: November 5, 2023
Scope: minor bug fixes and improvements since 5.10.0.
For a complete list of all closed issues and pull requests for this release, consult the 5.10.1 milestone page in the JUnit repository on GitHub.
JUnit Platform
Bug Fixes
-
Field predicates are now applied while searching the type hierarchy. This fixes bugs in
findFields(…)
andstreamFields(…)
inReflectionSupport
as well asfindAnnotatedFields(…)
andfindAnnotatedFieldValues(…)
inAnnotationSupport
.-
See issue 3532 for details.
-
-
Method predicates are now applied while searching the type hierarchy. This fixes bugs in
findMethods(…)
andstreamMethods(…)
inReflectionSupport
as well asfindAnnotatedMethods(…)
inAnnotationSupport
.-
See issue 3498 for details.
-
JUnit Jupiter
Bug Fixes
-
A package-private static field annotated with
@TempDir
is no longer shadowed by a non-static field annotated with@TempDir
when the non-static field resides in a different package and has the same name as the static field.-
See issue 3532 for details.
-
-
A package-private class-level lifecycle method annotated with
@BeforeAll
or@AfterAll
is no longer shadowed by a method-level lifecycle method annotated with@BeforeEach
or@AfterEach
when the method-level lifecycle method resides in a different package and has the same name as the class-level lifecycle method.-
See issue 3498 for details.
-
-
The
ON_SUCCESS
cleanup mode of@TempDir
now takes into account failures of test methods and nested tests when it’s declared on the class level, e.g. as a static field. -
The
RandomNumberExtension
example in the User Guide has been updated to properly supportInteger
types as well as non-static field injection.
5.10.0
Date of Release: July 23, 2023
Scope:
-
Promotion of various experimental APIs to stable
-
New
LauncherInterceptor
SPI -
New
testfeed
details mode forConsoleLauncher
-
New
ConsoleLauncher
subcommand for test discovery without execution -
Dry-run mode for test execution
-
New
NamespacedHierarchicalStore
for use in third-party test engines -
Stacktrace pruning to hide internal JUnit calls
-
New
@SelectMethod
support in test@Suite
classes. -
New
TempDirFactory
SPI for customizing how temporary directories are created -
Failure threshold for
@RepeatedTest
-
New convenience base classes for implementing
ArgumentsProvider
andArgumentConverter
-
Custom class loader support for class/method selectors,
@MethodSource
,@EnabledIf
, and@DisabledIf
-
Improved configurability of parallel execution
-
Numerous bug fixes and minor improvements
For a complete list of all closed issues and pull requests for this release, consult the 5.10.0-M1, 5.10.0-RC1, 5.10.0-RC2, and 5.10.0 GA milestone pages in the JUnit repository on GitHub.
JUnit Platform
Deprecations and Breaking Changes
-
Building native images with GraalVM now requires configuring the build arg
--initialize-at-build-time=org.junit.platform.launcher.core.LauncherConfig
and--initialize-at-build-time=org.junit.jupiter.engine.config.InstantiatingConfigurationParameterConverter
. -
The
getMethodParameterTypes()
methods inMethodSelector
andNestedMethodSelector
have been deprecated and replaced bygetParameterTypeNames()
for greater clarity.
New Features and Improvements
-
Various "experimental" APIs have been promoted to "stable", including
ModuleSelector
,EngineDiscoveryListener
,EngineDiscoveryRequestResolver
,LauncherSession
,LauncherSessionListener
, parallel execution support classes,@Suite
and related annotations, and others. -
All utility methods in
ReflectionSupport
that return aList
now have counterparts which return aStream
. -
New
tryToLoadClass(…)
variant inReflectionSupport
that accepts an explicitClassLoader
, allowing classes to be resolved with customClassLoader
arrangements. -
ReflectionSupport.findMethod(Class<?>, String, String)
now uses theClassLoader
of the suppliedClass
to load parameter types instead of using the defaultClassLoader
. This allows parameter types to be resolved with customClassLoader
arrangements (such as OSGi). Consequently,DiscoverySelectors.selectMethod(Class<?>, String, String)
also now works properly with customClassLoader
arrangements. -
New
@SelectMethod
selector support in the@Suite
test engine. -
Classes may now be selected by fully-qualified name via the
names
attribute in@SelectClasses
. -
New overloaded constructors for
ClassSelector
,NestedClassSelector
,MethodSelector
, andNestedMethodSelector
that take an explicitClassLoader
as a parameter, allowing selectors to select classes in customClassLoader
arrangements like in OSGi. -
New
selectMethod()
andselectNestedMethod()
variants inDiscoverySelectors
that accept aClass<?>…
argument of parameter types as a type-safe alternative to providing the names of parameter types as a comma-delimited string. -
For consistency with JUnit Jupiter lifecycle callbacks, listener method pairs for started/finished and opened/closed events are now invoked using "wrapping" semantics. This means that finished/closed event methods are invoked in reverse order compared to the corresponding started/opened event methods when multiple listeners are registered. This affects the following listener interfaces:
TestExecutionListener
,EngineExecutionListener
,LauncherDiscoveryListener
, andLauncherSessionListener
. -
New
LauncherInterceptor
SPI for intercepting the creation of instances ofLauncher
andLauncherSessionlistener
as well as invocations of thediscover
andexecute
methods of the former. Please refer to the User Guide for details. -
Support for limiting the
max-pool-size-factor
for parallel execution via a configuration parameter. -
New
testfeed
details mode forConsoleLauncher
that prints test execution events as they occur in a concise format. -
The existing functionality of the
ConsoleLauncher
has been split into two subcommands:execute
for executing tests andengines
for listing registered test engines. -
A new
discover
subcommand has been added to theConsoleLauncher
to print the discovered tests for the specified details mode without executing them. -
Improved error message for cyclic graphs detected during test discovery to be more actionable.
-
Extracted
NamespacedHierarchicalStore
from JUnit Jupiter engine for reuse by other test engines and their extensions. -
New dry-run mode to simulate test execution without actually running tests. Please refer to the User Guide for details.
-
Stack traces produced by failing tests are now pruned of calls from the
org.junit
,jdk.internal.reflect
, andsun.reflect
packages. This feature can be disabled via a configuration parameter. Please refer to the User Guide for details. -
New
getAncestors()
method inTestDescriptor
.
JUnit Jupiter
Bug Fixes
-
The extensions supporting
@MethodSource
,@EnabledIf
, and@DisabledIf
now load classes by fully-qualified class name using theClassLoader
obtained from the test class when possible. This allows classes to be resolved with customClassLoader
arrangements (such as OSGi). -
When converting an argument for a
@ParameterizedTest
method from a fully-qualified class name (String
) to aClass
, theClassLoader
of the class in which the@ParameterizedTest
method is declared is now used to resolve theClass
instead of the defaultClassLoader
.
Deprecations and Breaking Changes
-
The
dynamic
parallel execution strategy now allows the thread pool to be saturated by default. -
Implicit type conversion of boolean values like in
@CsvSource
is now stricter, only allowing values"true"
or"false"
(case-insensitive), in order to make accidental mistakes apparent and to avoid potential confusion.
New Features and Improvements
-
Various "experimental" APIs have been promoted to "stable", including
MethodOrderer
,ClassOrderer
,InvocationInterceptor
,LifecycleMethodExecutionExceptionHandler
,@TempDir
, parallel execution annotations, and others. -
JAVA_22
has been added to theJRE
enum for use with JRE-based execution conditions. -
New
reason
attribute in@Execution
which can be used to document the reason for using the selected execution mode. -
New
junit.jupiter.execution.parallel.config.dynamic.max-pool-size-factor
configuration parameter to set the maximum pool size factor. -
New
junit.jupiter.execution.parallel.config.dynamic.saturate
configuration parameter to disable pool saturation. -
@RepeatedTest
can now be configured with a failure threshold which signifies the number of failures after which remaining repetitions will be automatically skipped. See the User Guide for details. -
If
@MethodSource
is used with a non-static factory method that should bestatic
, the exception thrown now provides the user a meaningful explanation of how to address the problem. -
@EmptySource
now supports additional types, includingCollection
andMap
subtypes with a public no-arg constructor. -
New
ArgumentsAccessor.getInvocationIndex()
method that supplies the index of a@ParameterizedTest
invocation. -
New
AnnotationBasedArgumentsProvider
convenience base class which implements bothArgumentsProvider
andAnnotationConsumer
. -
New
AnnotationBasedArgumentConverter
convenience base class which implements bothArgumentConverter
andAnnotationConsumer
. -
@TempDir
can now be used as a meta-annotation in order to create custom composed annotations. See the@JimfsTempDir
example in the User Guide for details. -
@TempDir
now successfully cleans up files and directories on Windows that are set to read-only. -
New
TempDirFactory
SPI for customizing how the@TempDir
extension creates temporary directories. See the User Guide for details. -
The User Guide now includes an example implementation of the
RandomNumberExtension
in order to improve the documentation for extension registration via@ExtendWith
on fields. -
The scope of applicability for
TestWatcher
implementations is now more extensively documented in the User Guide and Javadoc. -
DisplayNameGenerator
methods are now allowed to returnnull
, in order to signal to fall back to the default display name generator.
5.9.3
Date of Release: April 26, 2023
Scope: Bug fixes and enhancements since 5.9.2
For a complete list of all closed issues and pull requests for this release, consult the 5.9.3 milestone page in the JUnit repository on GitHub.
JUnit Jupiter
Bug Fixes
-
Parameter types for local
@MethodSource
factory method names are now validated. For example,@MethodSource("myFactory(example.NonexistentType)")
will now result in an exception stating thatexample.NonexistentType
cannot be resolved to a valid type. -
The syntax for parameter types in local
@MethodSource
factory method names now supports canonical array names — for example, you may now specifyint[]
as in@MethodSource("myFactory(int[])")
instead of the binary name[I
as in@MethodSource("myFactory([I)")
(which was already supported) and@MethodSource("myFactory(java.lang.String[])")
instead of@MethodSource("myFactory([Ljava.lang.String;)")
. -
The search algorithm used to find
@MethodSource
factory methods now applies consistent semantics for local qualified method names and fully-qualified method names for overloaded factory methods. -
The
{displayName}
placeholder for@ParameterizedTest
invocation names is no longer parsed usingjava.text.MessageFormat
. Consequently, any text in the display name of the@ParameterizedTest
method will be included unmodified in the invocation display name. For example, Kotlin method names and custom display names configured via@DisplayName
can now contain apostrophes ('
) as well as text resemblingMessageFormat
elements such as{0}
or{data}
. -
Exceptions thrown for files that cannot be deleted when cleaning up a temporary directory created via
@TempDir
now include the root cause. -
Lifecycle methods are allowed to be declared as
private
again for backwards compatibility; however, usingprivate
visibility for lifecycle methods is strongly discouraged and will be disallowed in a future release.
New Features and Improvements
-
The search algorithm used to find
@MethodSource
factory methods now falls back to lenient search semantics when a factory method cannot be found by qualified name (without a parameter list) and also provides better diagnostics when a unique factory method cannot be found.
5.9.2
Date of Release: January 10, 2023
Scope: Bug fixes and enhancements since 5.9.1
For a complete list of all closed issues and pull requests for this release, consult the 5.9.2 milestone page in the JUnit repository on GitHub.
JUnit Platform
Bug Fixes
-
The Java 7 based constructor for
ForkJoinPool
is no longer accidentally used on Java 9 or higher when invalidParallelExecutionConfiguration
is provided. Instead, an exception is thrown for invalid configuration, thereby preventing invalid configuration from being silently ignored.
New Features and Improvements
-
New
TestPlan.getTestIdentifier(UniqueId)
andTestPlan.getChildren(UniqueId)
methods to avoid parsing unique IDs unnecessarily during test execution. -
Support for limiting the
max-pool-size
for parallel execution via a configuration parameter. -
Suite discovery now ignores cycles encountered in a test suite and logs an informational message at
CONFIG
level instead of throwing an exception.
JUnit Jupiter
Bug Fixes
-
New
@MethodSource
syntax for explicitly selecting an overloaded local factory method without specifying its fully qualified name.
Deprecations and Breaking Changes
-
The
fixed
parallel execution strategy now allows the thread pool to be saturated by default.
New Features and Improvements
-
JAVA_21
has been added to theJRE
enum for use with JRE-based execution conditions. -
New
junit.jupiter.execution.parallel.config.fixed.max-pool-size
configuration parameter to set the maximum pool size. -
New
junit.jupiter.execution.parallel.config.fixed.saturate
configuration parameter to disable pool saturation.
5.9.1
Date of Release: September 20, 2022
Scope:
-
New
@EnabledInNativeImage
and@DisabledInNativeImage
annotations for testing in GraalVM native images. -
Minor bug fixes and enhancements since 5.9.0
For a complete list of all closed issues and pull requests for this release, consult the 5.9.1 milestone page in the JUnit repository on GitHub.
JUnit Jupiter
Bug Fixes
-
Headers provided via the
value
attribute in@CsvSource
for a@ParameterizedTest
are now properly parsed when theuseHeadersInDisplayName
attribute is set totrue
. -
A
@ParameterizedTest
method configured with a@MethodSource
annotation that references a factory method inherited from multiple interfaces no longer fails with an exception stating that multiple factory methods with the same name were found. -
A
@ParameterizedTest
method configured with a@MethodSource
annotation that references a factory method whose name is the same as other non-factory methods in the same class no longer fails with an exception stating that multiple factory methods with the same name were found. -
Assertion failures thrown from methods with applied timeouts using
ThreadMode.SEPARATE
are now properly reported.
5.9.0
Date of Release: July 26, 2022
Scope:
-
XML reports in the new Open Test Reporting format
-
Configurable cleanup mode for
@TempDir
-
Configurable thread mode for
@Timeout
-
Conditional execution based on OS architectures
-
New
TestInstancePreConstructCallback
extension API -
Reusable parameter resolution for custom extension methods via
ExecutableInvoker
-
Parameter injection for
@MethodSource
methods -
New
IterationSelector
-
Various improvements to
ConsoleLauncher
-
Numerous bug fixes and minor improvements
For complete details consult the 5.9.0 Release Notes online.