This document contains the change log for all JUnit releases since 5.14 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.
6.0.0
Date of Release: ❓
Scope:
-
Java 17 and Kotlin 2.2 baseline
-
Single version number for Platform, Jupiter, and Vintage
-
Use of JSpecify annotations to document nullability
-
Integration of JFR functionality into
junit-platform-launcher
-
Removal of
junit-platform-runner
andjunit-platform-jfr
-
Switch to FastCSV library for
@CsvSource
and@CsvFileSource
-
Support for using Kotlin
suspend
functions as test methods -
Support for cancelling test execution via
CancellationToken
-
New
--fail-fast
mode for ConsoleLauncher -
Deterministic order of
@Nested
classes -
Inheritance of
@TestMethodOrder
by enclosed@Nested
classes -
MethodOrderer.Default
andClassOrderer.Default
for@Nested
classes -
Removal of various deprecated behaviors and APIs
For a complete list of all closed issues and pull requests for this release, consult the 6.0.0-M1, 6.0.0-M2, 6.0.0-RC1, 6.0.0-RC2, 6.0.0-RC3, and 6.0.0 milestone pages in the JUnit repository on GitHub.
Migration Guide
Please refer to the wiki for guidance on upgrading from JUnit 5.x.y to 6.0.0. |
Overall Improvements
Deprecations and Breaking Changes
-
Minimum required Java version is now 17.
-
Minimum required Kotlin version is now 2.2.
-
Platform artifacts now use the same version number as Jupiter and Vintage artifacts.
New Features and Improvements
-
All JUnit modules now use JSpecify nullability annotations to indicate which method parameters, return types, etc. can be
null
.
JUnit Platform
Deprecations and Breaking Changes
-
Remove deprecated support for running the
ConsoleLauncher
without specifying a subcommand. -
Remove support for deprecated non-conventional
ConsoleLauncher
options such as--h
(rather than-h
) or-help
(rather than--help
). -
The
junit-platform-runner
module that provided the JUnit 4 basedJUnitPlatform
runner has been discontinued. -
The
junit-platform-jfr
module that provided custom Java Flight Recorder (JFR) events for test discovery and execution has been discontinued. Instead, the functionality is now available directly injunit-platform-launcher
without requiring an additional dependency. -
Support for Maven Surefire/Failsafe versions less than 3.0.0 has been dropped.
-
The following deprecated APIs have been removed:
-
ReflectionSupport.loadClass(String)
method -
ReflectionUtils.readFieldValue(…)
methods -
ReflectionUtils.getMethod(…)
method -
BlacklistedExceptions
class -
PreconditionViolationException
class (fromorg.junit.platform.commons.util
) -
ClasspathScanningSupport
class -
ConfigurationParameters.size()
method -
MethodSelector.getMethodParameterTypes()
method -
NestedMethodSelector.getMethodParameterTypes()
method -
ReportEntry()
constructor -
SingleTestExecutor
class -
LauncherDiscoveryRequestBuilder()
constructor -
LegacyReportingUtils
class -
TestPlan.add(TestIdentifier)
,TestPlan.getChildren(String)
, andTestPlan.getTestIdentifier(String)
methods -
TestPlan.add(TestIdentifier)
andTestPlan.getChildren(String)
methods -
@UseTechnicalNames
annotation -
EngineTestKit.execute(String, EngineDiscoveryRequest)
,EngineTestKit.execute(TestEngine, EngineDiscoveryRequest)
, andEngineTestKit.Builder.filters(…)
methods
-
-
Support for "legacy semantics" for field and method searches that used to be configurable via the
junit.platform.reflection.search.useLegacySemantics
system property has been removed. JUnit now always adheres to standard Java semantics regarding whether a given field or method is visible or overridden according to the rules of the Java language. -
The type bounds of the following methods have been changed to be more flexible and allow nullable and non-nullable types:
-
ConfigurationParameters.get(String, Function)
-
NamespacedHierarchicalStore.getOrComputeIfAbsent(N, K, Function)
-
NamespacedHierarchicalStore.getOrComputeIfAbsent(N, K, Function, Class)
-
-
Discontinue
junit-platform-suite-commons
which is now integrated intojunit-platform-suite
. -
Deprecate
Launcher.execute(TestPlan, TestExecutionListener[])
andLauncher.execute(LauncherDiscoveryRequest, TestExecutionListener[])
in favor ofLauncher.execute(LauncherExecutionRequest)
-
ConversionSupport
now convertsString
toLocale
using the IETF BCP 47 language tag format supported by theLocale.forLanguageTag(String)
factory method instead of the format used by the deprecatedLocale(String)
constructor. -
Deprecate
getOrComputeIfAbsent(…)
methods inNamespacedHierarchicalStore
in favor of the newcomputeIfAbsent(…)
methods. -
Setting an invalid value for one of the following enum-based configuration parameters now causes test discovery to fail:
-
junit.platform.discovery.issue.failure.phase
-
junit.platform.discovery.issue.severity.critical
-
-
The methods
findNestedClasses
andstreamNestedClasses
inReflectionSupport
now return nested classes declared in the same enclosing class or interface ordered in a deterministic but intentionally nonobvious way. -
Serialization support for
TestIdentifier
has been changed in a backwards-incompatible way in order to simplify the implementation.
New Features and Improvements
-
Introduce new
Launcher.execute(LauncherExecutionRequest)
API with correspondingLauncherExecutionRequestBuilder
to enable the addition of parameters to test executions without additional overloads ofexecute(…)
. -
New
discoveryRequest()
method inLauncherDiscoveryRequestBuilder
(analogous toexecutionRequest(…)
inLauncherExecutionRequestBuilder
), which is an alias for the existingrequest()
method and is intended to be used via astatic
import. -
Introduce
LauncherDiscoveryRequestBuilder.forExecution()
method as a convenience method for constructing aLauncherExecutionRequest
that contains aLauncherDiscoveryRequest
. -
Introduce support for cancelling a running test execution via a
CancellationToken
passed to theLauncher
as part of aLauncherExecutionRequest
and from there to all registered test engines. Please refer to the User Guide for details and a usage example. -
Passing the
--fail-fast
option to theexecute
subcommand of theConsoleLauncher
now causes test execution to be cancelled after the first failed test. -
Provide cancellation support for implementations of
HierarchicalTestEngine
such as JUnit Jupiter, Spock, and Cucumber. -
Provide cancellation support for the
@Suite
test engine. -
Introduce
TestTask.getTestDescriptor()
method for use inHierarchicalTestExecutorService
implementations. -
Introduce
computeIfAbsent(…)
methods inNamespacedHierarchicalStore
to simplify working with non-nullable types. -
Stack traces are now pruned up to the test method or lifecycle method.
-
Convention-based conversion in
ConversionSupport
now supports factory methods and factory constructors that accept a singleCharSequence
argument in addition to the existing support for factories that accept a singleString
argument. -
Non-printable control characters in display names are now replaced with alternative representations. For example,
\n
is replaced with<LF>
. This applies to all display names in JUnit Jupiter,@SuiteDisplayName
, and any other test engines that subclassAbstractTestDescriptor
. Please refer to the User Guide for details. -
New
selectClasses(…)
andselectClassesByName(…)
factory methods have been introduced inDiscoverySelectors
to simplify use cases where one needs to select multiple individual test classes for theLauncher
orEngineTestKit
. -
New
selectors(List)
builder method forEngineTestKit
which can be used in conjunction with the newselectClasses(…)
andselectClassesByName(…)
factory methods inDiscoverySelectors
.
JUnit Jupiter
Bug Fixes
-
CSV headers are now properly supported with the default display name pattern and the explicit
{argumentsWithNames}
display name pattern for parameterized tests that utilize theuseHeadersInDisplayName
flag in@CsvSource
and@CsvFileSource
. Specifically, the parameter name is no longer duplicated in the display name when a CSV header is desired instead.
Deprecations and Breaking Changes
-
The following deprecated APIs have been removed:
-
MethodOrderer.Alphanumeric
class -
InvocationInterceptor.interceptDynamicTest(Invocation, ExtensionContext)
method
-
-
The deprecated
junit.jupiter.tempdir.scope
configuration parameter is no longer supported. -
The
JRE
enum constants forJAVA_8
toJAVA_16
have been deprecated because they can no longer be used at runtime sinceJAVA_17
is the new baseline. Please also manually update any values used with theminVersion
andmaxVersion
attributes in@EnabledForJreRange
and@DisabledForJreRange
or theversions
attributes in@EnabledOnJre
and@DisabledOnJre
to ensure that you are no longer declaring version values less than 17. -
@EnabledForJreRange
and@DisabledForJreRange
now useJAVA_17
as their defaultmin
value. -
The contracts for the
Executable
parameters of Kotlin-specificassertTimeout
functions were changed fromcallsInPlace(executable, EXACTLY_ONCE)
tocallsInPlace(executable, AT_MOST_ONCE)
which might result in compilation errors. -
As a result of migrating from univocity-parsers to FastCSV for
@CsvSource
and@CsvFileSource
, root causes and messages of exceptions thrown for malformed CSV input may differ in some cases. While the overall parsing behavior remains consistent, this may affect custom error handling that relies on specific exception types or messages. -
The
lineSeparator
attribute in@CsvFileSource
has been removed. The line separator is now automatically detected, meaning that any of\r
,\n
, or\r\n
is treated as a line separator. -
Attributes such as
ignoreLeadingAndTrailingWhitespace
,nullValues
, and others in@CsvSource
and@CsvFileSource
now apply to header fields as well as to regular fields. -
Extra characters after a closing quote are no longer allowed in
@CsvSource
and@CsvFileSource
. For example, if a single quote is used as the quote character, the following CSV value'foo’INVALID,'bar'
will now cause an exception to be thrown. This helps ensure that malformed input is not silently accepted or misinterpreted. -
The
junit-jupiter-migrationsupport
artifact and its contained classes are now deprecated and will be removed in the next major version. -
The type bounds of the following methods have been changed to be more flexible and allow nullable and non-nullable types:
-
ExtensionContext.getConfigurationParameter(String, Function)
-
ExtensionContext.getOrComputeIfAbsent(K, Function)
-
ExtensionContext.getOrComputeIfAbsent(K, Function, Class)
-
-
Change the return type of the
provideTestTemplateInvocationContexts(ExtensionContext)
method in theTestTemplateInvocationContextProvider
interface fromStream<TestTemplateInvocationContext>
toStream<? extends TestTemplateInvocationContext>
. -
Remove support for the
junit.jupiter.params.arguments.conversion.locale.format
configuration parameter.Locale
conversions are now always performed using the IETF BCP 47 language tag format supported by theLocale.forLanguageTag(String)
factory method. -
Deprecate
getOrComputeIfAbsent(…)
methods inExtensionContext.Store
in favor of the newcomputeIfAbsent(…)
methods. -
Setting an invalid value for one of the following enum-based configuration parameters now causes test discovery or execution to fail:
-
junit.jupiter.execution.parallel.mode.default
-
junit.jupiter.execution.parallel.mode.classes.default
-
junit.jupiter.execution.timeout.mode
-
junit.jupiter.execution.timeout.thread.mode.default
-
junit.jupiter.extensions.testinstantiation.extensioncontextscope.default
-
junit.jupiter.tempdir.cleanup.mode.default
-
junit.jupiter.testinstance.lifecycle.default
-
-
For consistency with test methods,
@Nested
classes declared in the same enclosing class or interface are now ordered in a deterministic but intentionally nonobvious way.
New Features and Improvements
-
Kotlin’s
suspend
modifier may now be applied to test and lifecycle methods. -
The
Arguments
interface for parameterized tests is now officially a@FunctionalInterface
. -
The implementation of
@CsvSource
and@CsvFileSource
has been migrated from the no longer maintained univocity-parsers to FastCSV. This improves the consistency of CSV input handling, including for malformed entries, and provides better error reporting and overall performance. -
Display names for
@ParameterizedClass
and@ParameterizedTest
now consistently style name-value pairs for arguments usingname = value
formatting – for example,fruit = apple
instead offruit=apple
. -
Reason strings supplied to
ConditionEvaluationResult
APIs are now officially declared as@Nullable
. -
Introduce
computeIfAbsent(…)
methods inExtensionContext.Store
to simplify working with non-nullable types. -
Text-based arguments in display names for parameterized tests are now quoted by default. In addition, special characters are escaped within quoted text. Please refer to the User Guide for details.
-
Fallback String-to-Object Conversion for parameterized tests now supports factory methods and factory constructors that accept a single
CharSequence
argument in addition to the existing support for factories that accept a singleString
argument. -
Non-printable control characters in display names are now replaced with alternative representations. Please refer to the User Guide for details.
-
For consistency with
@TestClassOrder
,@TestMethodOrder
annotations specified on a test class are now inherited by its@Nested
inner classes, recursively. -
Introduce
MethodOrderer.Default
andClassOrderer.Default
for reverting back to default ordering on a@Nested
class and its@Nested
inner classes when an enclosing class specifies a different orderer via@TestMethodOrder
or@TestClassOrder
, respectively.
JUnit Vintage
Deprecations and Breaking Changes
-
The JUnit Vintage engine is now deprecated and will report an INFO level discovery issue when it finds at least one JUnit 4 test class. For now, the intent of the deprecation is not to signal removal in the next major version but to clarify the intended purpose of the engine. It should only be used temporarily while migrating tests to JUnit Jupiter or another testing framework with native JUnit Platform support.
5.14.0-RC1
Date of Release: September 23, 2025
Scope:
-
Bug fixes and enhancements since 5.13.x
-
Deprecations along with new APIs to ease migration to the upcoming 6.0 release
For a complete list of all closed issues and pull requests for this release, consult the 5.14.0-RC1 milestone page in the JUnit repository on GitHub.
JUnit Platform
Bug Fixes
-
The
Launcher
(specificallyLauncherDiscoveryResult
) now retains the originalTestEngine
registration order after pruning test engines without tests, thereby ensuring reliable test execution order of multiple test engines.
Deprecations and Breaking Changes
-
Deprecate
OutputDirectoryProvider
interface in favor of the newOutputDirectoryCreator
interface to resolve cyclic package dependency along with the following APIs (which all have replacements working withOutputDirectoryCreator
):-
EngineDiscoveryRequest.getOutputDirectoryProvider()
-
ExecutionRequest.getOutputDirectoryProvider()
-
LauncherDiscoveryRequestBuilder.outputDirectoryProvider(OutputDirectoryProvider)
-
TestPlan.getOutputDirectoryProvider()
-
EngineTestKit.Builder.outputDirectoryProvider(OutputDirectoryProvider)
-
-
Deprecate
org.junit.platform.commons.support.Resource
interface in favor of the neworg.junit.platform.commons.io.Resource
one. -
Deprecate
Resource
-related methods inReflectionSupport
in favor of corresponding methods in newResourceSupport
class:-
findAllResourcesInClasspathRoot(URI, Predicate)
-
findAllResourcesInModule(String, Predicate)
-
findAllResourcesInPackage(String, Predicate)
-
streamAllResourcesInClasspathRoot(URI, Predicate)
-
streamAllResourcesInModule(String, Predicate)
-
streamAllResourcesInPackage(String, Predicate)
-
tryToGetResources(String)
-
tryToGetResources(String, ClassLoader)
-
-
Deprecate
DiscoverySelectors.selectClasspathResource(Set)
method in favor ofselectClasspathResourceByName(Set)
. -
Deprecate
ClasspathResourceSelector.getClasspathResources()
method in favor ofgetResources()
. -
Deprecate
EngineDiscoveryRequestResolver.Builder.addResourceContainerSelectorResolver(Predicate)
method in favor ofaddResourceContainerSelectorResolver(ResourceFilter)
. -
Deprecate
Resource
-related methods inClasspathScanner
in favor of new methods usingorg.junit.platform.commons.io.Resource
andResourceFilter
:-
scanForResourcesInPackage(String, Predicate)
-
scanForResourcesInClasspathRoot(URI, Predicate)
-
New Features and Improvements
-
Emit warning when
@SuiteDisplayName
is used with a blank string -
To help diagnosing potentially invalid invocations, the Console Launcher now logs warnings for nonexistent classpath roots added via
--classpath
or--scan-classpath
rather than silently ignoring them. -
New
FileSource.withPosition(FilePosition)
method to avoid the overhead of redundant canonicalization of files when usingFileSource.from(File, FilePosition)
with many differentFilePosition
instances for the sameFile
. -
New classpath resource abstraction in
org.junit.platform.commons.io.Resource
with support for loading resources or finding them on the classpath via static utility methods in the neworg.junit.platform.commons.support.ResourceSupport
class.
JUnit Jupiter
Deprecations and Breaking Changes
-
MediaType.APPLICATION_JSON_UTF_8
is now deprecated in favor of usingMediaType.APPLICATION_JSON
, since the industry considers UTF-8 to be the implicit default encoding for theapplication/json
media type. -
org.junit.jupiter.api.extension.MediaType
is now deprecated in favor of the neworg.junit.jupiter.api.MediaType
. -
The
publishFile(…)
methods inTestReporter
which accept anorg.junit.jupiter.api.extension.MediaType
are now deprecated in favor of new variants which accept anorg.junit.jupiter.api.MediaType
. -
The
publishFile(…)
method inExtensionContext
which accepts anorg.junit.jupiter.api.extension.MediaType
is now deprecated in favor of a new variant which accepts anorg.junit.jupiter.api.MediaType
. -
org.junit.jupiter.params.support.ParameterInfo
is now deprecated in favor of the neworg.junit.jupiter.params.ParameterInfo
.