Tools for JUnit 4 to 5 migration

A list of tools to support migrating from JUnit 4 to JUnit 5

Migrating from JUnit 4 to JUnit 5 is a lengthy manual process that you can make easier with these tools.

JUnit is by far the most popular unit testing framework for Java (84% of Java developers use it). While its current generation JUnit 5 has been available since 2017, the previous version JUnit 4 is still widely used. At the time of writing, about 8M Java files on GitHub contain JUnit 4 tests, while only about 3M contain JUnit 5 tests.

Upgrading to JUnit 5 brings a range of benefits, including:

  • More flexibility with JUnit 5’s support for modular and extensible architectures
  • Updated annotations including @BeforeEach, @AfterEach, @BeforeAll, and @AfterAll
  • Flexible assertions class
  • Powerful testing with built-in support for extensions
  • Support for parameterized testing, conditional test execution, and dynamic tests (for testing in runtime)
  • Support for tagging and filtering tests

👀 Differences between JUnit 4 vs JUnit 5: why upgrade?

For a complete overview of differences and a step-by-step description of a manual migration process, see our migration guide.

While migrating from JUnit 4 to 5 isn’t rocket science, it can take quite a bit of time in the case of large projects. There are several tools out there to (semi-) automate the upgrade process.

JUnit 4 to 5 migration tools

A note on using LLMs to migrate JUnit 4 to 5

While Large Language Models can be useful in tackling the upgrade from JUnit 4 to JUnit 5, they don’t provide deterministic results and suffer from problems such as hallucinations. Because of that, there’s some chance you’ll end up spending more time reworking your prompts and fixing code than the migration would have taken manually or than using one of the tools outlined below. In this post, we only look at deterministic solutions i.e. those that provide the exact same output for the exact same input every time. Tools are listed in an arbitrary order.

OpenRewrite

OpenRewrite is an automated refactoring ecosystem with predefined refactoring recipes (e.g. predefined, ready-to-use blueprints to transform code) like migration to Java 21, migration from Spring Boot 2 to 3, etc. OpenRewrite is a community-driven, open-source project, but is maintained by, and can be used with Moderne’s proprietary toolset for additional enterprise features (such as faster processing, multi-repo support, integrated team communication, etc).

OpenRewrite can be used to migrate large codebases to JUnit 5. It works by creating a Lossless Semantic Tree (LST) from your source code to execute the migration refactoring. Here’s a description of the migration process using one of OpenRewrite’s recipes.

Recipes cover a whole range of tasks including:

  • Upgrading to later Java versions
  • General code refactorings
  • Static code analysis and checkstyle issue resolution
  • Spring Boot 1 to 2 migration.

Symflower

Symflower is the only tool that offers fully automated migration from JUnit 4 to JUnit 5. Using Symflower enables a quick and efficient migration with no manual changes required. It’s an all-in-one solution that migrates code, packages, and dependencies.

Symflower is a CLI tool that covers a range of migration rules to update JUnit annotations, assertions, assumptions in your code. See the documentation for a detailed list of currently supported rules).

For an example of using Symflower in action, check out the guide in the tool’s documentation.

Automatically migrate JUnit 4 to JUnit 5.

Migration with IntelliJ IDEA

IntelliJ IDEA’s migration process can be considered a semi-automatic one. For instance, you’ll need to manually add JUnit 5 dependencies, and then use IntelliJ’s code suggestions to migrate chunks of code step by step.

Migrating with IntelliJ IDEA involves using the Find action to migrate JUnit 4 tests to JUnit 5, and using regex to remove references to JUnit 4 classes. More complex tests will need to be migrated manually.

Here’s the full tutorial for using IntelliJ IDEA to migrate from JUnit 4 to 5. There’s also the “Migrate” refactoring to make the process more simple. “Migrate” enables you to create a set of migration rules for a codebase. The tool also lets you edit existing migration rules to modify predefined settings, ensuring you can customize the migration process as needed.

migrate-to-junit5

migrate-to-Junit5 provides an “almost” automatic way to upgrade your codebase to JUnit 5. The tool relies on GNU AWK. You’ll run it from a Docker image so no additional dependencies are required. The process is described in this blog post.

migrate-to-junit5 does the following:

  • Migrate imports to the new JUnit 5 package names
  • Update annotations e.g. @Before -> @BeforeEach, @After -> @AfterEach, @Ignore -> @Disabled, etc.
  • When using the following runners with @RunWith:
    • SpringRunner/SpringJUnit4ClassRunner is transformed to SpringExtension
    • MockitoJUnitRunner is transformed to MockitoExtension
  • Test code updated to use assertThrows() when appropriate (when declaring exceptions the code should throw).

Using the tool is fairly straightforward: build the docker image, manually update pom.xml with dependencies, then use your editor to format code, optimize imports, and fix lambdas. The tool relies on IntelliJ’s built-in functionality for inspecting and updating code (e.g. when unnecessary curly braces are introduced by the migration).

Note that this tool doesn’t support @Rule, and you’ll need to remove unused imports manually. Another limitation is that in some situations, curly braces can confuse the script, so you’ll need to meticulously check the migrated code.

jSparrow

jSparrow is a code cleanup and refactoring tool for Java code that works with Eclipse. Like OpenRewrite, it offers a range of auto-refactor rules.

To migrate from JUnit 4 to 5, you’ll need to use:

You’ll need to combine several of jSparrow’s available rules for a successful migration. Migration with jSparrow can be considered a semi-manual process: while these auto-refactor rules are useful, they don’t come packaged into a “JUnit 4 to JUnit 5” set, you’ll need to manually select and use the appropriate ones.

Automatically migrate JUnit 4 to JUnit 5.
| 2024-12-03