Celebrations: Happy Thanksgiving to all our American readers!

Embracing JUnit 5 with Eclipse

Noopur Gupta
Eclipse JUnit 5
© Shutterstock / Sadovski

JUnit 5 is out the door as the next generation test framework! In this article, Noopur Gupta explains some useful tips and examples to help you work with it.

JUnit 5 is out the door as the next generation test framework. It is a fundamentally redesigned version of the most widely used testing library in Java. JUnit 4.0 was first released over a decade ago after the introduction of annotations in Java 5. The world of Java and testing has evolved a lot since then. JUnit 4 was a big ball of mud with a single junit.jar to be used by test developers, testing framework developers, IDE developers, and build tool developers. Over the time, these developers have been accessing internals and duplicating code from JUnit 4 to get things done. This had made it very difficult to maintain and enhance the JUnit framework. So, to take advantage of the new features like lambda expressions from Java 8 and to support the advanced testing needs, JUnit 5 is now available as a modular and extensible test framework for the modern era.

How is JUnit 5 different?

JUnit 5 is composed of several different modules from three different sub-projects.

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

  • JUnit Platform defines Launcher APIs which are used by IDEs and build tools to launch the framework. It also defines TestEngine APIs which are used to develop testing frameworks that run on the platform.
  • JUnit Jupiter is the combination of the new programming model and extension model for writing tests and extensions in JUnit 5. It also provides a TestEngine for running Jupiter based tests on the platform.
  • JUnit Vintage provides a TestEngine for running JUnit 3 and JUnit 4 based tests on the platform.

Give JUnit 5 a spin

To give JUnit 5 a spin, you have the tooling support in the Eclipse IDE ready at your disposal. Download Eclipse Oxygen.1a (4.7.1a) now and try it out yourself!

Here is a sneak peek into the major interesting features of JUnit Jupiter with Eclipse support for JUnit 5.

Eclipse JUnit 5

What can I do with JUnit 5?

Create a new JUnit Jupiter test

Create a new JUnit Jupiter test via New JUnit Test Case wizard:

Eclipse JUnit 5

On this page, you can specify the lifecycle method stubs to be generated for this test case. It also lets you select a class under test and on the next page, you can select the methods from this class to generate test stubs.

Add JUnit 5 library to the build path

  • The new JUnit Test Case wizard offers to add it while creating a new JUnit Jupiter test:

Eclipse JUnit 5

  • Quick Fix (Ctrl+1) proposal on @Test@TestFactory@ParameterizedTest, and @RepeatedTest annotations

Eclipse JUnit 5

  • Add JUnit library in Java Build Path dialog:

Eclipse JUnit 5

JUnit Jupiter test case

Here’s a simple JUnit Jupiter test case.

Eclipse JUnit 5

In JUnit Jupiter, test classes and methods can have any access modifier (other than private).

Here is a comparison of the annotations in JUnit 4 and JUnit Jupiter:

Eclipse JUnit 5

JUnit Jupiter test method

Create a JUnit Jupiter test method in the Eclipse IDE with the new test_jupiter template:

Eclipse JUnit 5

Assertions and Assumptions

JUnit Jupiter provides assertions and assumptions as static methods in org.junit.jupiter.api.Assertions class and org.junit.jupiter.api.Assumptions class respectively.

  • You can view all the failures from grouped assertions in the Result Comparison dialog which can be opened from the Failure Trace section of JUnit view:

Eclipse JUnit 5

  • You can view the number of tests with assumption failures on hover in JUnit view:

Eclipse JUnit 5

  • JUnit Jupiter’s Assertions, Assumptions, DynamicContainer and DynamicTest classes are now added to Eclipse Favorites by default:

Eclipse JUnit 5

This allows you to quickly import static methods in your code from these favorite classes via Content Assist (Ctrl + Space) and Quick Fix (Ctrl + 1).

You can also configure the number of static member imports needed in your code before type.* is used in the Organize Imports Preferences:

Eclipse JUnit 5

Custom display names

JUnit Jupiter’s @DisplayName annotation allows you to provide custom display names for test classes and test methods which can have spaces, special characters, and even emojis. In Eclipse, you can see the custom test names in JUnit view. You can use the Go to File action or you can just double-click on the custom test name to navigate to the corresponding test from JUnit view:

Eclipse JUnit 5

Nested test classes

In JUnit Jupiter, non-static nested classes (i.e. inner classes) can serve as @Nested test classes for logical grouping of test cases. In Eclipse, you can (re-)run a single nested test class by using the Run action in JUnit view or Outline view. You can even right-click on a nested test class name in the editor and use the Run As → JUnit Test action:

Eclipse JUnit 5

Test interfaces and default methods

JUnit Jupiter introduces the concept of a test interface which allows you to pre-implement some test code as default methods in interfaces. These default test methods can be inherited by implementing test classes, thereby enabling multiple inheritance in tests. In Eclipse, you can use the Go to File action or double-click on a test method in JUnit view to navigate to the corresponding default method inherited by the test class:

Eclipse JUnit 5

Tagging and filtering

You can tag test classes and test methods with your own identifiers using the @Tag annotation in JUnit Jupiter. These tags can later be used to filter test execution. In Eclipse, you can provide tags to be included in or excluded from a test run via the Configure Tags dialog in its JUnit launch configuration:

Eclipse JUnit 5

Meta-annotations and composed annotations

Annotations in JUnit Jupiter can be used as meta-annotations. This allows you to create a custom composed annotation that will automatically inherit the semantics of its meta-annotations. For example, you can use @Test and @Tag(“performance”) annotations as meta-annotations and create a composed annotation named @PerformaceTest which can be used as a replacement of the other two annotations on tests:

Eclipse JUnit 5

Dynamic tests

JUnit Jupiter introduces a concept of dynamic tests which are generated at runtime by a factory method annotated with @TestFactory annotation. The test factory method returns DynamicNode instances (DynamicContainer and DynamicTest). A dynamic container is composed of a display name and a list of dynamic nodes. A dynamic test is composed of a display name and an Executable. Note that there are no lifecycle callbacks for individual dynamic tests. Dynamic containers can be used for dynamic nesting of nodes:

Eclipse JUnit 5

In your Eclipse workspace, you can create a test factory method with the new test_factory template:

Eclipse JUnit 5

Repeated tests

You can repeat a test in JUnit Jupiter by annotating the test method with @RepeatedTest annotation and specifying the number of repetitions. You can optionally specify a custom display name for each repetition and use RepetitionInfo as the test method parameter to get information about the current repetition:

Eclipse JUnit 5

Eclipse JUnit 5

Parameterized tests

You can run a test multiple times with different arguments by annotating the test method with @ParameterizedTest annotation and declaring at least one source to provide the arguments. You can optionally specify a custom display name for each run. JUnit Jupiter provides various source annotations which can be seen in this example:

Eclipse JUnit 5

Eclipse JUnit 5

Dependency injection

Dependency injection in JUnit Jupiter allows test constructors and methods to have parameters. These parameters must be dynamically resolved at runtime by a registered parameter resolver. ParameterResolver is the extension API to provide parameter resolvers which can be registered via @ExtendWith annotation. This is where Jupiter’s programming model meets its extension model. JUnit Jupiter provides some built-in resolvers which are registered automatically:

  • TestInfo (resolved by TestInfoParameterResolver) to access information about the currently executing test:

Eclipse JUnit 5

  • TestReporter (resolved by TestReporterParameterResolver) to publish additional data about the current test run which can be seen in the Console view in the Eclipse IDE:

Eclipse JUnit 5

In the Eclipse IDE, the Test Method Selection dialog in JUnit launch configuration now shows the method parameter types also:

Eclipse JUnit 5

JUnit Jupiter extension model

JUnit Jupiter’s extension model provides various extension APIs as small interfaces in org.junit.jupiter.api.extension package which can be implemented by extension providers. You can register one or more of these extensions declaratively on a test class, test method, or composed annotation via @ExtendWith annotation. JUnit Jupiter also supports global extension registration via Java’s ServiceLoader mechanism:

Eclipse JUnit 5

Note

  • If you are using an Eclipse workspace where you were running your JUnit 5 tests via @RunWith(JUnitPlatform.class) in the Eclipse IDE without JUnit 5 support then you will have JUnit 4 as the test runner in their launch configurations. Before executing these tests in the Eclipse IDE with JUnit 5 support, you should either change their test runner to JUnit 5 or delete them so that new launch configurations are created with JUnit 5 test runner while running the tests:

Eclipse JUnit 5

  • We do not support running tests in a setup where an old Eclipse build (not having JUnit 5 support) is using a new Eclipse build (having JUnit 5 support) as target. Also, developers who have the JDT JUnit runtime bundles (org.eclipse.jdt.junit.runtimeorg.eclipse.jdt.junit4.runtime) checked out and pull the latest changes will run into the above issue. You are expected to use a new Eclipse build for the development.

Resources & References

Eclipse Support for JUnit 5

Learn more about the JUnit 5 Project

 

eclipseorb_color

This post was originally published in the October 2017 issue of the Eclipse Newsletter: Utility Belt: Projects and Tools

For more information and articles check out the Eclipse Newsletter.

Author

Noopur Gupta

Noopur Gupta is a software engineer at IBM India Software Labs. She’s a committer and co-lead of the Eclipse JDT project. 

Follow her on Twitter @noopur2507


Comments
comments powered by Disqus