This document contains the change log for all JUnit 5 releases since 5.7 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.8.1
Date of Release: September 22, 2021
Scope:
-
Support for text blocks in
@CsvSource -
Java 18 support in the
JREenum -
Access to the
ExecutionModein theExtensionContext -
Minor bug fixes and enhancements since 5.8.0
For a complete list of all closed issues and pull requests for this release, consult the 5.8.1 milestone page in the JUnit repository on GitHub.
JUnit Platform
Deprecations and Breaking Changes
-
@UseTechnicalNameshas been deprecated in favor of the new@Suitesupport which does not require the use of technical names. See the warning in Using JUnit 4 to run the JUnit Platform for details.
JUnit Jupiter
Bug Fixes
-
assertLinesMatch()inAssertionsno longer fails with aNoSuchElementExceptionif a limited fast-forward followed by at least one more expected line exceeds the remaining actual lines. -
assertLinesMatch()inAssertionsnow handles fast-forwards with leading and trailing spaces correctly and no longer throws anIndexOutOfBoundsException.
New Features and Improvements
-
JAVA_18has been added to theJREenum for use with JRE-based execution conditions. -
CSV content in
@CsvSourcecan now be supplied as a text block instead of an array of strings. See the User Guide for details and an example. -
The
ExecutionModefor the current test or container is now accessible via theExtensionContext.
5.8.0
Date of Release: September 12, 2021
Scope:
-
Declarative test suites via
@Suiteclasses -
LauncherSessionand accompanying listener -
New
UniqueIdTrackingListener -
More fine-grained Java Flight Recorder events
-
Java Flight Recorder support on Java 8 Update 262 or higher
-
Test class ordering
-
@TempDircan be used to create multiple temporary directories -
Extension registration via
@ExtendWithon fields and parameters -
Auto-close support for arguments in
@ParameterizedTestmethods -
Memory and performance optimizations
-
Numerous bug fixes and minor improvements
For a complete list of all closed issues and pull requests for this release, consult the 5.8 M1, 5.8 RC1, and 5.8 GA milestone pages in the JUnit repository on GitHub.
Overall Improvements
Deprecations and Breaking Changes
-
Since the API Guardian dependency is no longer exported as a runtime but rather as a compile-only dependency to consuming Gradle projects, Gradle builds that define their own dependency configurations may be affected. For example, if the custom configuration is used to manipulate a source set’s classpath directly, dependency attributes needed for Gradle’s variant-aware dependency management are dropped, and API Guardian is missing from the compile classpath. In that case, the Java compiler emits warnings which — depending on your configured options — may cause the build to fail. The solution is to avoid manipulating a source set’s classpath directly. Instead, its dependency configurations should extend from your custom configuration. An example of such a change can be seen in this commit to the Spring Framework repository.
New Features and Improvements
-
The API Guardian dependency is now exported as a compile-only dependency for consuming Gradle projects and no longer required at runtime when running on the module path.
-
Logging messages are no longer issued at
INFOlevel in order to lower the "textual noise" on the console when Java’s Util Logging is used in its default configuration.
JUnit Platform
Bug Fixes
-
Classes explicitly selected via
@SelectClassesare now always included in the test suite. This applies to@Suiteclasses running via theSuiteTestEngineand suite classes running via theJUnitPlatformRunner. -
SummaryGeneratingListeneris now thread-safe and can handle concurrently failing tests.
Deprecations and Breaking Changes
-
The
JUnitPlatformrunner has been deprecated in favor of the new@Suitesupport. See the warning in Using JUnit 4 to run the JUnit Platform for details. -
For consistency with the rest of the JUnit Platform, the experimental
LauncherDiscoveryListeneris now an interface instead of an abstract class.
New Features and Improvements
-
New
junit-platform-suite-enginemodule to execute declarative test suites on the JUnit Platform. See JUnit Platform Suite Engine for details. -
Additional selectors in the suite API in the
junit-platform-suite-apimodule. See the Javadoc of theorg.junit.platform.suite.apipackage for a full list of supported annotations and further details. -
New
UniqueIdTrackingListenerwhich is aTestExecutionListenerthat tracks the unique IDs of all tests that were skipped or executed during theTestPlanand generates a file containing the unique IDs. The generated file can be used to rerun those tests — for example, in order to run the same set of tests executed on the JVM subsequently within a GraalVM native image. See the Javadoc forUniqueIdTrackingListenerfor details. -
New
findAnnotation(Class,Class,SearchOption)method inAnnotationSupportthat performs the same search algorithm asfindAnnotation(AnnotatedElement,Class)but also searches the enclosing class hierarchy for inner classes if theINCLUDE_ENCLOSING_CLASSESSearchOptionis specified. This new method can be used by extension authors to find annotations on enclosing classes for JUnit Jupiter@Nestedtest classes. -
New
test(Condition<Event>)andnestedContainer(Class<?>, Condition<Event>)methods inEventConditionsthat allow you to provide conditions for matching against test and nested container events when using theEngineTestKit. For example,test(displayName("my test"))can be used to match against a test whose display name ismy test. -
Generating Java Flight Recorder (JFR) events via the
junit-platform-jfrmodule is now also supported on Java 8 Update 262 or higher, in addition to Java 11 or later. See Flight Recorder Support for details. -
The
junit-platform-jfrmodule now publishes execution events for containers — for example, test classes. -
The
junit-platform-jfrmodule now publishes test discovery events for the launcher and registered test engines. -
New
ClassSource.from(URI)static factory method for creating aClassSourcefrom a URI using theclassscheme and optional query parameters specifying the line number and column number. This is analogous to the existingClasspathResourceSource.from(URI)factory method. -
New
getConfigurationParameters()method in theTestPlanwhich allows aTestExecutionListenerto access configuration parameters. See Configuring an Execution Listener for details. -
Custom
LauncherDiscoveryListenerimplementations can now be registered via Java’sServiceLoadermechanism. -
Documented constant value of
ExclusiveResource.GLOBAL_KEY. -
Instances of
TestIdentifierandUniqueIdnow retain less memory because they no longer storeStringrepresentations of unique IDs. -
Tools that make multiple calls to the
LauncherAPI should now create aLauncherSessionin order to allow for executing global setup and teardown code exactly once via the newLauncherSessionListenerinterface that can be registered via Java’sServiceLoadermechanism.
JUnit Jupiter
Bug Fixes
-
@DisplayNameGenerationand@IndicativeSentencesGenerationare now only inherited from enclosing classes if the current class is a@Nestedtest class. -
The
IndicativeSentencesDisplayNameGeneratorno longer includes the display name of the enclosing class when generating an indicative sentence if the enclosing class is not configured to use theIndicativeSentencesdisplay name generator as well. -
The
TypedArgumentConverterbase class now supports the conversion of anullsource value in parameterized tests. -
The
TypedArgumentConverterbase class now supports conversion to a primitive type if the configured target type is a wrapper for the target primitive type, including primitive widening support — for example, fromIntegertointorlong. -
Exceptions thrown from instances of
CloseableResourceno longer hide test failures but are instead reported as suppressed exceptions.
Deprecations and Breaking Changes
-
The new
autoCloseArgumentsfeature in@ParameterizedTestmay potentially be a breaking change for existing parameterized test methods if an argument that implementsjava.lang.AutoCloseableis reused for multiple invocations of the same parameterized test method. If your parameterized test methods start to fail when you upgrade to JUnit Jupiter 5.8, you can disable this feature by declaring@ParameterizedTest(autoCloseArguments = false). -
InvocationInterceptor.interceptDynamicTest(Invocation<Void>, ExtensionContext)has been deprecated in favor ofInvocationInterceptor.interceptDynamicTest(Invocation<Void>, DynamicTestInvocationContext, ExtensionContext)that provides access to the dynamic test executable viaDynamicTestInvocationContext.getExecutable().
New Features and Improvements
-
Test classes can now be ordered globally by supplying the fully-qualified name of a class implementing the
ClassOrdererAPI as the value of the newjunit.jupiter.testclass.order.defaultconfiguration parameter. See Class Order for details. -
@Nestedtest classes can be ordered locally via the new@TestClassOrderannotation in which aClassOrderercan be specified. -
@ExtendWithmay now be used to register extensions declaratively via fields or parameters in test class constructors, test methods, and lifecycle methods. See Declarative Extension Registration for details. -
@RegisterExtensionfields may now beprivate. -
New
assertThrowsExactly()method inAssertionswhich is a more strict version ofassertThrows()that allows you to assert that the exception thrown is of the exact type specified. -
assertDoesNotThrow()inAssertionsnow supports suspending functions when called from Kotlin. -
New
assertInstanceOf()methods which produce better error messages comparable to those produced byassertThrows. These new methods serve as a replacement forassertTrue(obj instanceof X). -
assertNull()failure messages now include the actual object’s type if thetoString()implementation for the actual object returnsnullor"null". This avoids the generation of confusing failure messages such asexpected <null> but was <null>. -
@TempDircan now be used to create multiple temporary directories. Instead of creating a single temporary directory per context (i.e. test class or method) every declaration of the@TempDirannotation on a field or method parameter now results in a separate temporary directory. To revert to the old behavior of using a single temporary directory for the entire test class or method (depending on which level the annotation is used), you can set thejunit.jupiter.tempdir.scopeconfiguration parameter toper_context. -
@TempDircleanup resets readable and executable permissions of the root temporary directory and any contained directories instead of failing to delete them. -
@TempDirfields may now beprivate. -
DynamicTests.stream()can now consumeNamedinput and will use each name-value pair as the display name and value for each generated dynamic test (see User Guide for details). -
New
classURI scheme for dynamic test sources. This allows tests to be located using the information available in aStackTraceElement. -
Dynamic tests now require less memory thanks to a number of improvements to internal data structures.
-
New
autoCloseArgumentsattribute in@ParameterizedTestto closejava.lang.AutoCloseablearguments after each invocation of the parameterized test method. This attribute defaults totrue. -
Numeric literals used with
@CsvSourceorCsvFileSourcecan now be expressed using underscores as in some JVM languages, to improve readability of long numbers like700_000_000. -
CSV rows provided via
@CsvSourcemay now start with a number sign (#). -
New
ignoreLeadingAndTrailingWhitespaceattributes in@CsvSourceand@CsvFileSource(set totrueby default) to control whether or not to trim whitespace. -
In parameterized tests using
@MethodSourceor@ArgumentSource, arguments can now have optional names (supplied via the newNamedAPI). When the argument is included in the display name of an invocation, this name will be used instead of the value. -
Documented constant values in
org.junit.jupiter.api.parallel.Resources.
JUnit Vintage
Bug Fixes
-
If multiple exceptions are registered as failures for a JUnit 4 based test — for example, if the
ErrorCollectorrule throws anorg.junit.runners.model.MultipleFailureException— all of those failures are now added as suppressed exceptions in theorg.opentest4j.MultipleFailuresErrorcreated by theVintageTestEngine. This allows users to analyze the stack trace of each failure when such a test fails.
5.7.2
Date of Release: May 15, 2021
Scope: Bug fixes since 5.7.1
For a complete list of all closed issues and pull requests for this release, consult the 5.7.2 milestone page in the JUnit repository on GitHub.
JUnit Platform
Bug Fixes
-
Method
getRootUrisForPackage()in classClasspathScannernow returns a valid list of class names when the package name is equal to the name of a module on the module path and when running on Java 8. -
Direct child descriptors of the engine descriptor now also acquire the global read lock when they require other exclusive resources.
5.7.1
Date of Release: February 4, 2021
Scope: Bug fixes since 5.7.0
For a complete list of all closed issues and pull requests for this release, consult the 5.7.1 milestone page in the JUnit repository on GitHub.
General bug fixes
-
For compatibility with
JarInputStream, all JARs now containMETA-INF/andMETA-INF/MANIFEST.MFas their first entries again.
JUnit Platform
Bug Fixes
-
StringUtils.nullSafeToString()now returns"null"if the invocation oftoString()on the supplied object returnsnull. Although this is an internal utility, the effect of this change may be witnessed by end users and test engine or extension authors. -
Method
scanForClassesInPackage(String)inClasspathScannernow returns a valid list of class names when the package name is equal to the name of a module on the module path. -
The legacy XML report now always includes container-level failures (e.g. from
@BeforeAllJupiter lifecycle methods).
JUnit Jupiter
Bug Fixes
-
If the
toString()implementation of an argument passed to a@ParameterizedTestmethod returnsnull, the display name formatter for the parameterized test now treats the name of the corresponding argument as"null"instead of throwing an exception. This fixes a regression introduced in JUnit Jupiter 5.7.0. -
Creator functions passed to
ExtensionContext.Store.getOrComputeIfAbsent()are now only called once even if they throw an exception.
New Features and Improvements
-
The user guide now explains Nested Tests in more detail.
-
New utility method in
TestInstancePreDestroyCallbackhelps to ensure all test instances are processed when used in conjunction with@Nestedtests. -
JAVA_17has been added to theJREenum for use with JRE-based execution conditions.
5.7.0
Date of Release: September 13, 2020
Scope:
-
Promotion of experimental features in JUnit Platform and Jupiter
-
Java Flight Recorder support
-
TestKit improvements
-
@Isolatedtests -
Configurable default method orderer
-
Custom disabled reasons for all
@Enabled*/@Disabled*annotations -
Improvements to
assertTimeoutPreemptively() -
Improvements to
@CsvFileSourceand@CsvSource
For complete details consult the 5.7.0 Release Notes online.