The JUnit 5 framework is the latest version of JUnit, and it consists of three subcomponents: JUnit Platform, JUnit Jupiter, and JUnit Vintage. Before learning about these components. JUnit 5 runtime requires Java version 8 (or any higher version). But unit tests can still be compiled with older versions of Java and run with JUnit 5.
JUnit is the testing framework’s foundation, which helps develop the framework. JUnit Jupiter is used to write tests, and JUnit Vintage is used to run older versions (JUnit 3 or JUnit 4) of JUnit tests.
JUnit 5 vs JUnit 4
Let us explore the differences between JUnit 5 and JUnit 4.
- In JUnit 4, everything is configured and packaged differently than it is in JUnit 5. JUnit 5 is made up of three parts: JUnit Platform, JUnit Jupiter, and JUnit Vintage.
- JUnit 4 supports Java 5 (or higher) and JUnit 5 supports Java 8 (or higher).
- The JUnit framework confirms they are an important part. In JUnit 4, assertions (or assertions) are composed into the org.junit.Assert package containing all assertions. In JUnit 5, assertion methods are composed and can be imported from org.junit.jupiter.
- It’s different when assertion error messages are returned.
- In unit 4, assertEquals public static void (string message, long overdue, real long).
- In unit 5, General constant void assertion (expected long, real long, string message)
Advantages of Module 5
- There are some obvious limitations to JUnit 4. The entire framework was in a single jar library. Even when only a specific feature is needed, the entire library should be imported.
- JUnit 5 allows us to import what is necessary. The test runner only supports running tests using JUnit 4 (for example, using SpringJUnit4ClassRunner or Parameterized). JUnit 5 allows multiple broker mechanisms to operate simultaneously.
- JUnit 4 has never been compatible with Java beyond version 7, it has lost many features from Java 8. JUnit 5 takes advantage of many Java 8 features. The goal of JUnit 5 was to completely rewrite JUnit 4 in order to solve most of these issues.
Major differences between JUnit 5 and JUnit 4.
Architecture
JUnit 4 has everything contained within a single jar file.
JUnit 5 is composed of three subcomponents, namely JUnit Platform, JUnit Jupiter, and JUnit Vintage.
- The JUnit platform defines the TestEngine API for developing new testing frameworks that run on the platform.
- JUnit Jupiter includes all new JUnit annotations and a TestEngine implementation to run tests written with these annotations.
- JUnit Vintage is intended to support running JUnit 3 and JUnit 4 written tests on the JUnit 5 platform.
Required JDK Version
- JUnit 4 requires Java 5 or higher.
- JUnit 5 requires Java 8 or higher.
Assertions
In JUnit 4, org.junit.Assert contains all the assert methods used to verify expected outcomes.
The method signature accepts extra parameters for error messages. e.g.
public static void assertEquals(long expected, long actual) public static void assertEquals(String message, long expected, long actual)
In JUnit 5, org.junit.jupiter.Assertions contain most of the assert() methods, including additional assertThrows()
, assertAll()
methods.
JUnit 5 assertion methods also have overloaded methods to support parsing error messages in case tests fail, for example
public static void assertEquals(long expected, long actual) public static void assertEquals(long expected, long actual, String message) public static void assertEquals(long expected, long actual, Supplier messageSupplier)
Assumptions
In Junit 4, org.junit.Assume has methods for stating assumptions about the conditions in which a test is meaningful. It has the following five methods:
- assumeFalse()
- assumeNoException()
- assumeNotNull()
- assumeThat()
- assumeTrue()
In Junit 5, org.junit.jupiter.api.Assumptions are used to state assumptions about the conditions in which a test is meaningful It has the following three methods:
- assumeFalse()
- assumingThat()
- assumeTrue()
Tagging and Filtering
- In Junit 4,
@category
annotation is used. - In Junit 5,
@tag
annotation is used.
Test Suites
In Junit 4, @RunWith
and @Suite
annotation. e.g.
import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ ExceptionTest.class, TimeoutTest.class }) public class JUnit4Example{ }
In Junit 5, @Suite,
@SelectPackages
and @SelectClasses
e.g.
import org.junit.platform.runner.JUnitPlatform; import org.junit.platform.suite.api.SelectPackages; import org.junit.runner.RunWith; @Suite @SelectPackages("com.howtodoinjava.junit5.examples") public class JUnit5Example { }
Non-public Test Methods are Allowed
- JUnit 5 tests don’t have to be public. Now, we are able to make them package-protected.JUnit uses reflection to find test classes and test methods. It is not necessary for them to be public since reflection can still discover them even if they have limited visibility.
- JUnit test classes are also allowed to have non-public constructors. They can have arguments with one another. The public no-args constructor is not mandatory in JUnit 5.
class SeleniumTest { private SeleniumTest(TestInfo testInfo) { System.out.println("Working on test " + testInfo.getDisplayName()); } @Test void test(){ assertTrue(true); } }
3rd Party Integration
JUnit 4 lacks integration support for third-party plugins and IDEs. They need to rely on reflection.
The JUnit Platform project in JUnit 5 is dedicated to this purpose. It defines the TestEngine API for building a testing framework that runs on the platform.
Conclusion
In this tutorial, we familiarized ourselves with the important differences between the JUnit 4 and JUnit 5 frameworks and the tests written with them. Although there are many fundamental differences under the hood, the main difference is the modularity introduced in JUnit 5 and the support for writing custom runtime engines by third-party providers.