This document contains the change log for all JUnit releases since 5.13 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-M2
Date of Release: July 22, 2025
Scope:
-
New
LauncherExecutionRequestAPI -
Support for cancelling test execution via
CancellationToken -
New
--fail-fastmode for ConsoleLauncher -
Null-safe
computeIfAbsentmethods for stores -
Strict evaluation of enum-based configuration parameters
For a complete list of all closed issues and pull requests for this release, consult the 6.0.0-M2 milestone page in the JUnit repository on GitHub.
JUnit Platform
Deprecations and Breaking Changes
-
Discontinue
junit-platform-suite-commonswhich is now integrated intojunit-platform-suite. -
Deprecate
Launcher.execute(TestPlan, TestExecutionListener[])andLauncher.execute(LauncherDiscoveryRequest, TestExecutionListener[])in favor ofLauncher.execute(LauncherExecutionRequest) -
ConversionSupportnow convertsStringtoLocaleusing 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 inNamespacedHierarchicalStorein 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
-
New Features and Improvements
-
Introduce new
Launcher.execute(LauncherExecutionRequest)API with correspondingLauncherExecutionRequestBuilderto enable the addition of parameters to test executions without additional overloads ofexecute(…). -
Introduce
LauncherDiscoveryRequestBuilder.forExecution()method as a convenience method for constructing aLauncherExecutionRequestthat contains aLauncherDiscoveryRequest. -
Introduce support for cancelling a running test execution via a
CancellationTokenpassed to theLauncheras part of aLauncherExecutionRequestand from there to all registered test engines. Please refer to the User Guide for details and a usage example. -
Passing the
--fail-fastoption to theexecutesubcommand of theConsoleLaunchernow causes test execution to be cancelled after the first failed test. -
Provide cancellation support for implementations of
HierarchicalTestEnginesuch as JUnit Jupiter, Spock, and Cucumber. -
Provide cancellation support for the
@Suitetest engine. -
Introduce
TestTask.getTestDescriptor()method for use inHierarchicalTestExecutorServiceimplementations. -
Introduce
computeIfAbsent(…)methods inNamespacedHierarchicalStoreto simplify working with non-nullable types.
JUnit Jupiter
Deprecations and Breaking Changes
-
Change the return type of the
provideTestTemplateInvocationContexts(ExtensionContext)method in theTestTemplateInvocationContextProviderinterface fromStream<TestTemplateInvocationContext>toStream<? extends TestTemplateInvocationContext>. -
Remove support for the
junit.jupiter.params.arguments.conversion.locale.formatconfiguration parameter.Localeconversions are now always performed using the IETF BCP 47 language tag format supported by theLocale.forLanguageTag(String)factory method. -
Deprecate
getOrComputeIfAbsent(…)methods inExtensionContext.Storein 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
-
New Features and Improvements
-
Display names for
@ParameterizedClassand@ParameterizedTestnow consistently style name-value pairs for arguments usingname = valueformatting – for example,fruit = appleinstead offruit=apple. -
Reason strings supplied to
ConditionEvaluationResultAPIs are now officially declared as@Nullable. -
Introduce
computeIfAbsent(…)methods inExtensionContext.Storeto simplify working with non-nullable types.
6.0.0-M1
Date of Release: June 27, 2025
Scope:
-
Java 17 and Kotlin 2.2 baseline
-
Single version number for Platform, Jupiter, and Vintage
-
Use of JSpecify annotations to document nullability
-
Removal of various deprecated behaviors and APIs
-
Integration of JFR functionality into
junit-platform-launcher -
Removal of
junit-platform-runnerandjunit-platform-jfr -
Switch to FastCSV library for
@CsvSourceand@CsvFileSource -
Support for using Kotlin
suspendfunctions as test methods
For a complete list of all closed issues and pull requests for this release, consult the 6.0.0-M1 milestone page in the JUnit repository on GitHub.
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
ConsoleLauncherwithout specifying a subcommand. -
Remove support for deprecated non-conventional
ConsoleLauncheroptions such as--h(rather than-h) or-help(rather than--help). -
The
junit-platform-runnermodule that provided the JUnit 4 basedJUnitPlatformrunner has been discontinued. -
The
junit-platform-jfrmodule 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-launcherwithout 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 -
BlacklistedExceptionsclass -
PreconditionViolationExceptionclass (fromorg.junit.platform.commons.util) -
ClasspathScanningSupportclass -
ConfigurationParameters.size()method -
MethodSelector.getMethodParameterTypes()method -
NestedMethodSelector.getMethodParameterTypes()method -
ReportEntry()constructor -
SingleTestExecutorclass -
LauncherDiscoveryRequestBuilder()constructor -
LegacyReportingUtilsclass -
TestPlan.add(TestIdentifier),TestPlan.getChildren(String), andTestPlan.getTestIdentifier(String)methods -
TestPlan.add(TestIdentifier)andTestPlan.getChildren(String)methods -
@UseTechnicalNamesannotation -
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.useLegacySemanticssystem 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)
-
JUnit Jupiter
Deprecations and Breaking Changes
-
The following deprecated APIs have been removed:
-
MethodOrderer.Alphanumericclass -
InvocationInterceptor.interceptDynamicTest(Invocation, ExtensionContext)method
-
-
The deprecated
junit.jupiter.tempdir.scopeconfiguration parameter is no longer supported. -
The
JREenum constants forJAVA_8toJAVA_16have been deprecated because they can no longer be used at runtime sinceJAVA_17is the new baseline. Please also manually update any values used with theminVersionandmaxVersionattributes in@EnabledForJreRangeand@DisabledForJreRangeor theversionsattributes in@EnabledOnJreand@DisabledOnJreto ensure that you are no longer declaring version values less than 17. -
@EnabledForJreRangeand@DisabledForJreRangenow useJAVA_17as their defaultminvalue. -
The contracts for the
Executableparameters of Kotlin-specificassertTimeoutfunctions 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
@CsvSourceand@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
lineSeparatorattribute in@CsvFileSourcehas been removed. The line separator is now automatically detected, meaning that any of\r,\n, or\r\nis treated as a line separator. -
Attributes such as
ignoreLeadingAndTrailingWhitespace,nullValues, and others in@CsvSourceand@CsvFileSourcenow apply to header fields as well as to regular fields. -
Extra characters after a closing quote are no longer allowed in
@CsvSourceand@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-migrationsupportartifact 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)
-
New Features and Improvements
-
Kotlin’s
suspendmodifier may now be applied to test and lifecycle methods. -
The
Argumentsinterface for parameterized tests is now officially a@FunctionalInterface. -
The implementation of
@CsvSourceand@CsvFileSourcehas 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.
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.13.4
Date of Release: July 21, 2025
Scope: Bug fixes and enhancements since 5.13.3
For a complete list of all closed issues and pull requests for this release, consult the 5.13.4 milestone page in the JUnit repository on GitHub.
5.13.3
Date of Release: July 4, 2025
Scope: Bug fixes and enhancements since 5.13.2
For a complete list of all closed issues and pull requests for this release, consult the 5.13.3 milestone page in the JUnit repository on GitHub.
JUnit Jupiter
Bug Fixes
-
Fix regression that caused top-level and static member classes annotated with
@Nestedto no longer be executed because they caused a discovery issue to be reported. -
Stop reporting discovery issues for composed annotation classes that are meta-annotated with
@Nested. -
Stop reporting discovery issues for
DefaultImplsclasses generated by the Kotlin compiler for interfaces with non-abstract test methods. -
When a
customReasonis supplied along with anullvalue for the defaultreasontoConditionEvaluationResult.disabled(String, String), the resulting reason is now"my custom reason"instead of"null ==> my custom reason".
New Features and Improvements
-
A blank reason supplied to a
ConditionEvaluationResultfactory method is now treated the same as anullreason, resulting in an emptyOptionalreturned fromConditionEvaluationResult.getReason(). -
The Javadoc for factory methods in
ConditionEvaluationResultnow explicitly states that bothnulland blank values are supported for reason strings and that such values will result in an emptyOptionalreturned fromConditionEvaluationResult.getReason(). -
Improve message of discovery issues reported for ineffective
@Orderannotations.
5.13.2
Date of Release: June 24, 2025
Scope: Bug fixes and enhancements since 5.13.1
For a complete list of all closed issues and pull requests for this release, consult the 5.13.2 milestone page in the JUnit repository on GitHub.
JUnit Platform
Bug Fixes
-
If Git information is included in the Open Test Reporting XML format (see below), any credentials that may be configured as part the
remote.origin.urlsetting in Git were previously written to theoriginUrlattribute of<git:repository>elements. For example, when cloning a GitHub repository using a URL likehttps://username:[email protected]/organization/repository.git, both username and password were included in the XML report. Since a report which includes this information may be shared, published, or archived (for example, on a CI server), this was reported as a potential security vulnerability (CVE-2025-53103). Any credentials are now replaced with***before writing them to the XML report.
Deprecations and Breaking Changes
-
Including information about the Git repository (such as the commit hash and branch name) in the Open Test Reporting XML format is now an opt-in feature that can be enabled via a configuration parameter. Please refer to the User Guide for details.
JUnit Jupiter
Bug Fixes
-
Stop reporting discovery issues for cyclic inner class hierarchies not annotated with
@Nested. -
Stop reporting discovery issues for abstract inner classes that contain test methods but are not annotated with
@Nested. -
Stop reporting discovery issues for abstract test methods. Although they will not be executed, it is a valid pattern to annotate them with
@Testfor documentation purposes and override them in subclasses while re-declaring the@Testannotation.
5.13.1
Date of Release: June 7, 2025
Scope: Bug fixes and enhancements since 5.13.0
For a complete list of all closed issues and pull requests for this release, consult the 5.13.1 milestone page in the JUnit repository on GitHub.
JUnit Jupiter
Bug Fixes
-
The 5.13.0 release introduced a regression regarding the execution order in test classes containing both test methods and
@Nestedtest classes. When classpath scanning was used during test discovery — for example, when resolving a package selector for a@Suiteclass — test methods in@Nestedclasses were executed before test methods in their enclosing class. This undesired change in behavior has now been reverted so that tests in@Nestedtest classes are always executed after tests in enclosing test classes again. -
Fix support for
AnnotationBasedArgumentsProviderimplementations that override the deprecatedprovideArguments(ExtensionContext, Annotation)method.
5.13.0
Date of Release: May 30, 2025
Scope:
-
Introduce
@ClassTemplateand@ParameterizedClasssupport in JUnit Jupiter -
Access to
ParameterInfofor JUnit Jupiter extensions -
New
@SentenceFragmentannotation for use withIndicativeSentencesdisplay name generator -
Add
--redirect-stdoutand--redirect-stderroptions toConsoleLauncher -
Introduce test discovery support in
EngineTestKit -
Reporting of discovery issues for test engines
-
Resource management for launcher sessions and execution requests
-
GraalVM: removal of
native-image.propertiesfiles from JARs -
Bug fixes and other minor improvements
For a complete list of all closed issues and pull requests for this release, consult the 5.13.0-M1, 5.13.0-M2, 5.13.0-M3, 5.13.0-RC1, and 5.13.0 milestone pages in the JUnit repository on GitHub.
Overall Changes
Deprecations and Breaking Changes
-
The JUnit feature in GraalVM Native Build Tools (NBT) has been rewritten to no longer require JUnit classes to be initialized at build time when running on JDK 22 and later. Therefore, JUnit’s JARs no longer ship with
native-image.propertiesfiles that contain--initialize-at-build-timeoptions (introduced in 5.12.0). Please update to the most recent version of GraalVM Native Build Tools prior to upgrading to this version of JUnit. Please refer to the Upgrade Instructions in the wiki for details if you’re on NBT 0.10.x or earlier.
JUnit Platform
Bug Fixes
-
Notify
LauncherDiscoveryListenerimplementation registered viaLaucherConfigor on theLauncherofselectorProcessedevents. -
Reintroduce support for JVM shutdown hooks when using the
-cp/--classpathoption of theConsoleLauncher. Prior to this release, the created class loader was closed prior to JVM shutdown hooks being invoked, which caused hooks to fail with aClassNotFoundExceptionwhen loading classes during shutdown. -
Fix support of
--uidand--select-unique-idoptions in the console launcher.
New Features and Improvements
-
Introduce a mechanism for
TestEngineimplementations to report issues encountered during test discovery. If an engine reports aDiscoveryIssuewith aSeverityequal to or higher than a configurable critical severity, its tests will not be executed. Instead, the engine will be reported as failed during execution with a failure message listing all critical issues. Non-critical issues will be logged but will not prevent the engine from executing its tests. The critical severity can be configured via a new configuration parameter and, currently, defaults toERROR. Please refer to the User Guide for details.If you’re a test engine maintainer, please see the User Guide for details on how to start reporting discovery issues.
-
Start reporting discovery issues for problematic
@Suiteclasses:-
Invalid
@Suiteclass declarations (for example, whenprivate) -
Invalid
@BeforeSuite/@AfterSuitemethod declarations (for example, when notstatic) -
Cyclic dependencies between
@Suiteclasses
-
-
Introduce resource management mechanism that allows preparing and sharing state across executions or test engines via stores that are scoped to a
LauncherSessionorExecutionRequest. The Jupiter API uses these stores as ancestors to theStoreinstances accessible viaExtensionContextand provides a new method to access them directly. Please refer to the User Guide for examples of managing session-scoped and request-scoped resources. -
New
ConsoleLauncheroptions--redirect-stdoutand--redirect-stderrfor redirectingstdoutandstderroutput streams to files. -
Add
TestDescriptor.Visitor.composite(List)factory method for creating a composite visitor that delegates to the given visitors in order. -
Introduce test discovery support in
EngineTestKitto ease testing for discovery issues produced by aTestEngine. Please refer to the User Guide for details. -
Make validation of including
EngineFiltersmore strict to avoid misconfiguration, for example, due to typos. Prior to this release, an exception was only thrown when none of a filter’s included IDs matched any engine. Now, an exception is thrown if at least one included ID across all filters did not match any engine.
JUnit Jupiter
Bug Fixes
-
If the
autoCloseArgumentsattribute in@ParameterizedTestis set totrue, all arguments returned by registeredArgumentsProviderimplementations are now closed even if the test method declares fewer parameters. -
AutoCloseablearguments returned by anArgumentsProviderare now closed even if they are wrapped withNamed. -
AutoCloseablearguments returned by anArgumentsProviderare now closed even if a failure happens prior to invoking the parameterized method. -
Validate all versions specified in
@EnabledOnJreand@DisabledOnJreannotations.
New Features and Improvements
-
New
@ClassTemplateannotation andClassTemplateInvocationContextProviderAPI that allow declaring a top-level or@Nestedtest class as a template to be invoked multiple times. This may be used, for example, to inject different parameters to be used by all tests in the class template or to set up each invocation of the class template differently. Please refer to the User Guide for details. -
New
BeforeClassTemplateInvocationCallbackandAfterClassTemplateInvocationCallbackextension callback interfaces allow implementing extensions that are invoked before and after each invocation of a class template. -
New
@ParameterizedClasssupport that builds on@ClassTemplateand allows declaring a top-level or@Nestedtest class as a parameterized test class to be invoked multiple times with different arguments. The same@…Sourceannotations supported with@ParameterizedTestmay be used to provide arguments via constructor or field injection. Please refer to the User Guide for details. -
New
@ParameterizedClass-specific@BeforeParameterizedClassInvocation/@AfterParameterizedClassInvocationlifecycle methods that are invoked once before/after each invocation of the parameterized class. -
Provide access to the parameters and resolved arguments of a
@ParameterizedTestor@ParameterizedClassby storingParameterInfoin theExtensionContext.Storefor retrieval by other extensions. Please refer to the Javadoc for details. -
New
@SentenceFragmentannotation which allows one to supply custom text for individual sentence fragments when using theIndicativeSentencesDisplayNameGenerator. See the updated documentation in the User Guide for an example. -
New
TestTemplateInvocationContext.prepareInvocation(ExtensionContext)callback method which allows extensions to prepare theExtensionContextbefore the test template method is invoked. This may be used, for example, to store entries in theExtensionContext.Storeto benefit from its cleanup support or for retrieval by other extensions. -
Start reporting discovery issues for potentially problematic test classes:
-
Invalid
@Testand@TestTemplatemethod declarations (for example, when return type is notvoid) -
Invalid
@TestFactorymethods (for example, when return type is invalid) -
Multiple method-level annotations (for example,
@Testand@TestTemplate) -
Invalid test class and
@Nestedclass declarations (for example,static@Nestedclasses) -
Potentially missing
@Nestedannotations (for example, non-abstract inner classes that contain test methods) -
Invalid lifecycle method declarations (for example, when
private) -
Invalid
@Tagsyntax -
Blank
@DisplayNamedeclarations -
Blank
@SentenceFragmentdeclarations -
@BeforeParameterizedClassInvocationand@AfterParameterizedClassInvocationmethods declared in non-parameterized test classes
-
-
By default,
AutoCloseableobjects put intoExtensionContext.Storeare now treated like instances ofCloseableResource(which has been deprecated) and are closed automatically when the store is closed at the end of the test lifecycle. It’s possible to revert to the old behavior via a configuration parameter. Please also see the migration note for third-party extensions wanting to support both JUnit 5.13 and earlier versions. -
java.util.Localearguments are now converted according to the IETF BCP 47 language tag format. See the User Guide for details. -
Avoid reporting potentially misleading validation exception for
@ParameterizedClasstest classes and@ParameterizedTestmethods as suppressed exception for earlier failures. -
Add support for Kotlin
Sequenceto@MethodSource,@FieldSource, and@TestFactory. -
Allow publishing files to an existing directory via
TestReporterandExtensionContext, for example, when re-running a test class.