Home >Common Problem >JUnit, 4, 5, Jupiter, Retro
The release of JUnit 5 simplifies integrating this library into projects since there is no need to migrate from JUnit 4. However, in a large project using both JUnit 5 and 4, this coexistence can cause confusion and maintenance difficulties. To solve this problem, this article recommends taking the following steps: informing teams about new features in JUnit 5, encouraging writing new tests using JUnit 5, and following the Scout rule when removing JUnit 4. Additionally, this article explores notable changes in JUnit 5, including updates to annotations, methods, and test configurations, as well as the new @ParameterizedTest annotation. Finally, the article highlights the importance of excluding dependencies, creating configuration classes, and using OpenRewrite to automatically refactor your source code to help migrate to JUnit 5 and keep your project up to date.
After JUnit 5 was released, many developers just added this awesome new library to their projects because unlike other versions, in this new version, there is no need to migrate from JUnit 4 to 5, just include the new library in your project, with all engines of JUnit 5, you can use JUnit 5 for new tests and old tests with JUnit 4 or 3 will continue to run without problems.
But what happens in a large project, a project built 10 years ago, with two versions of JUnit running in parallel?
New developers have started working on the project, some with JUnit experience and some without. New tests are created using JUnit 5, new tests are created using JUnit 4, at some point, developers without knowing it, when they create new scenarios in already created JUnit 5 tests, they just include JUnit 4 annotations, and tests became a hybrid, some @Test were JUnit 4, some @Test were JUnit 5, and it became harder to remove JUnit 4 libraries every day.
So, how to solve this problem? First, you need to show your team what comes from JUnit 5 and what comes from JUnit 4 so that new tests can be created using JUnit 5 instead of JUnit 4. After that, whenever they pass the JUnit 4 tests, following the Boy Scout rules, they have to migrate to JUnit 5.
Let’s take a look at the major changes released in JUnit 5. It all starts with the name, in JUnit 5 you don't see a package named org.junit5, you see org.junit.jupiter. All in all, everything you see has "Jupiter" in it, which means it's from JUnit 5. They chose this name because Jupiter, which begins with "JU," is the fifth planet from the sun.
Another change is about @Test, this annotation was moved to a new package: org.junit.jupiter.api and now no longer uses properties like "expected" or "timeout", but Use extensions. For example, for timeout, now you have an annotation: @Timeout(value = 100, unit = TimeUnit.MILLISECONDS). Another change is that neither the test method nor the class needs to be public.
@Before Now instead of @After you have to use @BeforeEach and @AfterEach in the test configuration and you also have @BeforeAlland @AfterAll.
To ignore a test, you now have to use @Disable instead of @Ignore.
One of the good news released in JUnit 5 is the annotation @ParameterizedTest, which can run one multiple times with different parameters test. For example, if you want to test a method that creates an object, and you want to verify that the fields are filled in correctly, you would simply do the following:
@ParameterizedTest @MethodSource("getInvalidSources") void shouldCheckInvalidFields(String name, String job, String expectedMessage) { Throwable exception = catchThrowable(() -> new Client(name, job)); assertThat(exception).isInstanceOf(IllegalArgumentException.class) .hasMessageContaining(expectedMessage); } static Stream<Arguments> getInvalidSources() { return Stream.of(Arguments.arguments("Jean Donato", "", "Job is empty"), Arguments.arguments("", "Dev", "Name is empty")); }
JUnit There are a lot of nice features in JUnit 5, I recommend you check out the JUnit 5 User Guide to analyze which features will be useful for your project.
Now that all developers know what has changed in JUnit 5, you can begin the process of removing JUnit 4 from your project. So if you are still using JUnit 4 in 2024, and your project is a big one, you may have some dependencies that use JUnit 4. I recommend you profile your libraries to check if some of them are using JUnit 4.
In the image below, I am using IntelliJ’s dependency analyzer.
As you can see, jersey-test is using JUnit 4, that is, even if I remove JUnit 4 from the project, JUnit 4 still works, Because of Jersey. The easier way would be to upgrade jersey to 2.35 since JUnit 5 was introduced in jersey-test 2.35, but I can't update jersey-test framework because other libraries will break in my project. So, what can I do in this situation?
I can exclude JUnit from Jersey through Maven's dependency exclusion (as shown in the image below). This will no longer use JUnit 4, but our JUnit 5.
当你运行一些使用Jersey的测试时,它们不会被加载,因为Jersey中有使用JUnit 4注释的方法,setUpand tearDown,using@Before和@After。为了解决这个问题,您可以创建一个“配置类”,其扩展JerseyTest实现setUpandtearDown并@BeforeEach调用@AfterEachand 。super.setUp()super.TearDown()
public class JerseyConfigToJUnit5 extends JerseyTest { @BeforeEach public void setUp() throws Exception { super.setUp(); } @AfterEach public void tearDown() throws Exception { super.tearDown(); } }
因此,如果您已经检查了您的库并且没有人对 JUnit 4 有更多依赖,那么您终于可以将所有测试迁移到 JUnit 5,对于此过程,有一个很好的工具可以帮助您节省大量工作,那就是OpenRewrite,一个源代码的自动重构生态系统,它们会将您所有的旧包、旧注释和所有内容更改为新包。
就是这样,伙计们,现在您和您的队友可以享受 JUnit 5 并放松心情,因为知道将使用 JUnit 5 创建新测试,并且该项目不会成为弗兰肯斯坦。所以,记住,保持你的项目是最新的,因为如果你忘记了你的库,每一天都会更难更新,总是使用规范,以及遵循规范的框架,并且在你的代码中有一个好的设计,这允许您随设施改变和移动。
The above is the detailed content of JUnit, 4, 5, Jupiter, Retro. For more information, please follow other related articles on the PHP Chinese website!