Exploring JUnit 5
JUnit 5 is the most widely-used testing framework for Java applications. In this blog, we take a look at what makes it so popular, its dependencies, architecture, and the types of testing you can perform.
What Is JUnit 5?
JUnit 5 is the most current version of the JUnit testing Framework used for unit testing of projects that are using Java programming language.
Whenever a company releases an application, it faces the risk of whether the audience accepts and starts using it. There are many factors that have an impact on the user experience, but one of the top ones is the quality of the application.
Applications are usually very complex solutions that are communicating together. The code itself in applications is divided into small parts called “units.” In object-oriented programming languages (of which Java is one), those units are represented by classes and methods.
As applications are being developed and new features are added, you are sometimes touching the old code. This can change the behavior of the code, which can impact different units of the code that are communicating with the unit you’ve changed. We call this a “bug.” One of the ways how to avoid bugs in the application is to test the code.
With JUnit, developers can write tests for units of code. Due to the design, these tests are usually very quick so they can be run very often. Unit tests are also used in TDD – Test Driven Development.
JUnit Maven Dependency
To start testing your code using JUnit, you first need to have the library available in the project. If you are using Maven, your first steps should be going to your favorite IDE and open the project configuration file
pom.xml. The magic step that adds support for Junit5 is adding the dependency. Keep in mind that JUnit 5 requires Java 8 to work. To start using the framework, just edit your
pom.xml by adding the following dependency:
This will add the essentials you need to start working with JUnit 5. One of the advantages of JUnit 5 is its granularity. You can use only the libraries that you really need by including/excluding them.
JUnit 5 Architecture
One could think that JUnit 5 is solely a testing framework and that it’s. While this is theoretically right, JUnit is actually composed of three modules: JUnit Platform, JUnit Jupiter, and JUnit Vintage.
The Platform module is an essential module that runs the tests on the JVM.
The Jupiter module provides programmers the new combination of the programming model and extension for writing tests on JUnit 5.
The Vintage module allows running tests from older versions (JUnit 3 and JUnit 4) on the platform.
JUnit 5 Annotations
Framework JUnit 5 comes with some new features, including new annotations. Let’s take a look at the most important ones.
@DisplayName - Tests can have names
This might not seem like worth mentioning but, from my point of view, this is great. Every test and every method can be now annotated with @DisplayName(“Some name”). The name is then used in the results. On the example below, you can see that Class and one of the methods is using the new annotation:
The difference between the test results is shown here:
@Tag – Run tests with specific tag
If you want to run tests only from one specific group, use tags. With the new annotation, you can tag classes or methods.
@BeforeAll and @AfterAll
Sometimes there is a need to prepare the environment before the tests are executed or you want to clear it after the test is done. Those are things that take a lot of time and it doesn’t make sense to execute them over and over again.
A method marked with this annotation will be executed before all tests or after all test methods in the class, respectively. In JUnit 4, this was known as @BeforeClass and @AfterClass.
This annotation is used to disable the test class or method. In JUnit 4, this was known as @Ignore.
The big change in Assertions is that you can now use new features from Java 8. Speaking about tests, it means you can take full advantage of lambda expressions in assertions.
Another way to include groups of tests is to aggregate multiple test classes. This is a new feature of JUnit 5 and is achieved by using the following two annotations:
The class annotated with the above will run all the tests in the selected package(s). To show you both annotations in action, this is the project structure that I’m going to use:
Example of @SelectPackages:
After executing the example above, only tests in package “calculator” were run.
In case you want to run a test for a specific class or multiple cases, use this annotation:
After executing the example above, only tests in class "WeatherServiceTest" were run.
Exception testing in JUnit 5 is very simple. You just need to use the assertThrows() method.
All the tests mentioned above are static tests. What does that mean? This means they are annotated with @Test and are specified at compile time, meaning they cannot be changed during runtime.
A new feature in JUnit 5 is a dynamic test. These tests are generated during runtime and annotated with @TestFactory.
Above is a very simple example of a dynamic test that returns Collection. This is mandatory because the dynamic test must return DynamicNode, Stream, Collection, Iterable, Iterator, or array of DynamicNode.
You can see that there are new features in JUnit 5, as well as updates to existing features. The new iteration is more just an evolution of the JUnit testing framework.
If you are just starting with a new project, consider using JUnit 5. If you are now using JUnit 4 and thinking about switching to the newest version, remember that some things work differently (i.e. you can no longer use @Test and specify expectations in the value).
Looking for more information on JUnit or unit testing? Take a look at these other resources:
- JUnit Cheat Sheet
- The Right Methods For Unit Testing in Java
- Mock and Unit Testing With TestNG, JUnit and Mockito
- Guide to Testing Types in Software
See how much time JRebel can save you — sign up for a free 14-day trial!