The JUnit team continues to make steady work refining and improving on JUnit 5. In this article we will take a look at some of the new features and changes that are in JUnit 5.3 which was released on September 3rd. Also in this article we will look at some recent changes and improvements to libraries and tools that are often used in conjunction with JUnit.
Parallel Test Execution
I covered parallel test execution in a previous blog article. If you want an technical and in-depth look at the parallel execution features in JUnit 5.3, give that article a read. Here is a high level overview of parallel test execution in JUnit 5.3:
- Parallel test execution is enabled and configured through the build file (i.e. pom.xml, build.gradle)
- Parallel test execution behavior can be modified at the method and class level with the annotations:
Be sure to check out the user guide for more detailed information on configuring and using parallel test execution in JUnit 5.
Note: This feature has been reverted in 5.3.1
T̶h̶e̶ ̶a̶s̶s̶e̶r̶t̶T̶h̶r̶o̶w̶s̶ ̶a̶s̶s̶e̶r̶t̶i̶o̶n̶ ̶h̶a̶s̶ ̶b̶e̶e̶n̶ ̶u̶p̶d̶a̶t̶e̶d̶ ̶t̶o̶ ̶d̶i̶s̶p̶l̶a̶y̶ ̶t̶h̶e̶ ̶v̶a̶l̶u̶e̶ ̶r̶e̶t̶u̶r̶n̶e̶d̶ ̶f̶r̶o̶m̶ ̶a̶ ̶m̶e̶t̶h̶o̶d̶,̶ ̶i̶f̶ ̶a̶n̶y̶,̶ ̶w̶h̶e̶n̶ ̶a̶n̶ ̶e̶x̶c̶e̶p̶t̶i̶o̶n̶ ̶i̶s̶ ̶n̶o̶t̶ ̶t̶h̶r̶o̶w̶n̶.̶ ̶T̶h̶i̶s̶ ̶c̶a̶n̶ ̶b̶e̶ ̶h̶e̶l̶p̶f̶u̶l̶ ̶w̶h̶e̶n̶ ̶d̶e̶b̶u̶g̶g̶i̶n̶g̶ ̶a̶ ̶t̶e̶s̶t̶ ̶c̶a̶s̶e̶ ̶t̶h̶a̶t̶ ̶h̶a̶s̶ ̶s̶t̶a̶r̶t̶e̶d̶ ̶f̶a̶i̶l̶i̶n̶g̶.̶ ̶H̶e̶r̶e̶ ̶i̶s̶ ̶a̶ ̶s̶c̶r̶e̶e̶n̶s̶h̶o̶t̶ ̶o̶f̶ ̶w̶h̶a̶t̶ ̶t̶h̶i̶s̶ ̶d̶i̶s̶p̶l̶a̶y̶ ̶l̶o̶o̶k̶s̶ ̶l̶i̶k̶e̶ ̶i̶n̶ ̶E̶c̶l̶i̶p̶s̶e̶.̶ ̶I̶n̶ ̶t̶h̶i̶s̶ ̶e̶x̶a̶m̶p̶l̶e̶ ̶a̶n̶ ̶e̶m̶p̶t̶y̶ ̶L̶i̶s̶t̶ ̶i̶s̶ ̶b̶e̶i̶n̶g̶ ̶r̶e̶t̶u̶r̶n̶e̶d̶ ̶i̶n̶s̶t̶e̶a̶d̶ ̶o̶f̶ ̶t̶h̶e̶ ̶e̶x̶p̶e̶c̶t̶e̶d̶ ̶e̶x̶c̶e̶p̶t̶i̶o̶n̶.
Capturing Console Output
With JUnit 5.3 it is possible to capture System.out and System.err output using a
TestExecutionListener. Capturing console output isn’t a frequent need, but might be necessary if working on more legacy code bases where statements are frequently being written to console and it would be nice to see what is being written in a report.
To start capturing console output it requires two steps:
1. Implementing a TestExecutionListener
2. Configuring surefire to start capturing console output.
Here is an example of each:
Library and Tool Updates
As mentioned in the introduction of this article, we will be taking a look at updates to some other projects often used with JUnit. Most of these changes are unrelated too (i.e. not dependent upon) JUnit 5.3, but I wanted to cover them here as they happened relatively recently.
Surefire Native Support
Back in June the maven surefire team released version 2.22.0 of their plugin. With this release the surefire (and failsafe 2.22.0) plugin offer native support for JUnit 5. This is a nice, because prior to the 2.22.0 release, using JUnit 5 required a lot of additional configuration which was frankly a bit of an eyesore. Prior to 2.22.0, to run JUnit 5 with surefire this configuration was required:
With 2.22.0 the default surefire configuration can look like this:
Note: For spring boot projects, you need only add maven-surefire-plugin.version to your properties, like this.
Note 2: JUnit 5.3 has a bug that prevents tests from being found when the reuseForks tag is set to false. Read more here.
Filtering Changes with Native Support
However with native support comes changes with how tag filtering behaves. When using the JUnit surefire-provider in 2.21.0 filtering by tags looked like this:
However this does not work when running maven-surefire-plugin 2.22.0. To pass to surefire which tags you want to filter on you must use the groups, for which tests to execute, and excludeGroups, for which tests should not be executed, tags. Here is the 2.22.0 equivalent example of the above:
Enhanced Mockito Dependency Injection Support
As the tweet from @sam_brannen states, you can now directly inject mockito mocks via constructor or method parameters. This can make help make tests more declarative as to what they depend upon and/or a little cleaner. These changes were added in 2.21.0¹, here is an example of those changes in action:
AssertJ Soft Assertions and opentest4J
I have covered AssertJ in a previous blog post. With 3.11.1 AssertJ will now use the
MultipleFailuresError in the opentest4j library, if it’s available. opentest4j is a library created by the JUnit 5 team to help make the testing experience more consistent across projects for both users and library developers.
If you are not familiar with soft assertions, they are a way of asserting multiple values in a single test and instead of the test failing on the first assertion, all the failed assertions are instead collected and reported at the end of the test. This can help avoid the irritating loop of a test failing, fixing the failure, running the test again, and hitting another failure. Here’s a look at soft assertions in AssertJ:
Running this test will return both assertion failures, instead of just reporting that the first assert failed.
The JUnit team continues to make great progress on JUnit 5 adding new features, improving on existing ones, and fixing bugs as they are reported. This is only a highlight of some of the new features and changes coming in JUnit 5.3. For a full list of all the changes and improvements coming besure to check out the release notes and the JUnit 5 user guide on how to use the features as well.
1: Technically the changes were added in 2.20.3, but that is only available from the mockito’s maven repository, not maven central.