JUnit 5 is the latest version of JUnit, which mainly consists of three different subcomponents: JUnit Platform, JUnit Jupiter, and JUnit Vintage. Before learning about these components, a prerequisite about JUnit 5 is that the JUnit 5 runtime requires Java version 8 (or any higher version). However, unit tests can still be compiled with older versions of Java and tested with JUnit 5. Now let me explain the above three subcomponents.
The JUnit platform is the foundation of the testing framework, which helps in the development of the framework. JUnit Jupiter is used to writing tests and JUnit Vintage is used to run older versions of JUnit tests such as JUnit 3 and JUnit 4 based tests.
Let us understand the differences between JUnit 5 and JUnit 4
JUnit 4 has some obvious limitations. The entire framework was contained in a single jar library. The entire library should be imported even when only a specific feature is needed.
In JUnit 5 we get more details and can only import what is necessary. The test runner can only run tests on JUnit 4 at a time (eg SpringJUnit4ClassRunner or Parameterized). JUnit 5 allows multiple brokers to operate simultaneously.
JUnit 4 has never advanced beyond Java 7, it has lost many features of Java 8. JUnit 5 makes good use of Java 8 features. The idea behind JUnit 5 was to completely rewrite JUnit 4 to solve most of these issues.
Unit 4 is broken down into JUnit 5 modules:
JUnit Platform: This module covers all the extension frameworks that we may be interested in testing.
JUnit Vintage:This module allows backward compatibility with JUnit 4 or even JUnit 3.
The expected parameter in JUnit 4:
The timeout attribute in JUnit 4:
@Test(timeout = 1)
public void shouldFailBecauseTimeout() throws InterruptedException {
Thread.sleep(10);
}
Now, the assertTimeout method in JUnit 5:
Other annotations that were changed within JUnit 5:
We can now write assertion messages in a Lambda in JUnit 5, allowing the lazy evaluation to skip complex message construction until needed:
We can also group assertions in JUnit 5:
The new assumptions category is now at org.junit.jupiter.api.Assumptions. JUnit 5 fully supports the existing guessing methods in JUnit 4 and adds a bunch of new methods to allow only certain assertions to be executed in specific scenarios:
In JUnit 4 we can compile tests using the Category annotation. With JUnit 5, the Category annotation is replaced by the Tag annotation:
@Tag("annotations")
@Tag("junit5")
@RunWith(JUnitPlatform.class)
public class AnnotationTestExampleTest {
/*...*/
}
We can include/exclude particular tags using the maven-surefire-plugin:
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<properties>
<includeTags>junit5</includeTags>
</properties>
</configuration>
</plugin>
</plugins>
</build>
RunWith was used to integrate the test context with other frameworks or to change the general execution flow in test cases in Unit 4.
With JUnit 5 we can now use the ExtendWith annotation to provide similar functionality. As an example, to use Spring functions in Module 4:
In JUnit 4, the @Rule and @ClassRule annotations were used to add special functionality to tests.
In JUnit 5, we can reproduce the same logic using the @ExtendWith annotation.
For example, say we have a custom rule in JUnit 4 to write log traces before and after a test:
In addition, we implement it in a test suite:
Using the JUnit 5 interfaces AfterEachCallback and BeforeEachCallback provided in the org.junit.jupiter.api.extension package, we could easily implement this rule in the test suite:
JUnit Vintage aids in the migration of JUnit tests by running JUnit 3 or JUnit 4 tests within the JUnit 5 context.
We can use it by importing the JUnit Vintage Engine:
If you have any questions about software testing or need to extend your existing QA capabilities, contact QASource for a free quote.