自从JUnit 5发布后,很多开发者都将这个出色的新库添加到他们的项目中,因为与之前的版本不同,在这个新版本中,不需要从JUnit 4迁移到5,你只需要在项目中包含新的库,使用JUnit 5的引擎,你就可以用JUnit 5进行新的测试,而旧的JUnit 4或3的测试将继续运行而不会出现问题。
但在一个大型项目中,一个十年前构建的并行运行两个版本JUnit的项目中可能会发生什么?
新的开发者开始在这个项目上工作,其中一些人具有JUnit的经验,另一些人则没有。新的测试使用JUnit 5创建,新的测试也使用JUnit 4创建,在某个时候,一个不具备知识的开发者在创建一个已经用JUnit 5创建的测试新场景时,他们只是包含了一个JUnit 4的注解,测试就变成了混合体,一些JUnit 4的@Test
和一些JUnit 5的@Test
,而且每天去掉JUnit 4库都变得更加困难。
那么,如何解决这个问题呢?首先,你需要向你的团队展示哪些是JUnit 5的,哪些是JUnit 4的,这样新的测试就会使用JUnit 5而不是JUnit 4创建。之后,需要遵循童子军规则,每当他们通过一个JUnit 4的测试时,都必须迁移到JUnit 5。
让我们看看JUnit 5中发布的主要变化。首先从名字开始,在JUnit 5中,你不会看到名为org.junit5的包,而是org.junit.jupiter。概括来说,所有带有“Jupiter”的东西,意味着它来自JUnit 5。他们选择这个名字是因为Jupiter以“JU”开头,是距离太阳第五颗行星。
另一个变化是关于@Test
,这个注解被移到了一个新的包:org.junit.jupiter.api,现在不再使用像“expected”或“timeout”这样的属性,而是使用扩展。例如,对于超时,现在有一个用于这个的注解:@Timeout(value = 100, unit = TimeUnit.MILLISECONDS)
。另一个变化是测试方法或类不需要是public的。
现在在测试配置中,你需要使用@BeforeEach
和@AfterEach
来替代@Before
和@After
,你还可以使用@BeforeAll
和@AfterAll
。
为了忽略测试,现在你需要使用@Disable
而不是@Ignore
。
A great news that was released in JUnit 5 was the annotation @ParameterizedTest
, with that is possible to run one test multiple times with different arguments. For example, if you want to test a method that creates some object and you want to validate if the fields are filled correctly, you just 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 5中有许多很好的特性,我建议你查看JUnit 5的用户指南,以分析对你的项目有什么用。
现在所有开发者都知道了JUnit 5中进行了哪些更改,您可以开始从项目中移除JUnit 4的过程。所以,如果您在2024年仍在使用JUnit 4,并且您的项目是一个大型项目,您可能会有一些使用JUnit 4的依赖。我建议您分析您的库,查看其中是否有使用JUnit 4的。
在下面的图片中,我正在使用IntelliJ的依赖分析器。
如您所见,jersey-test正在使用JUnit 4,也就是说,即使我从我的项目中移除了JUnit 4,JUnit 4仍然可以通过Jersey使用。最简单的方法是将jersey升级到2.35,因为从jersey-test 2.35开始引入了JUnit 5,但我无法更新jersey-test框架,因为这会导致项目中的其他库出现问题。所以,在这种情况下,我能做什么呢?
I can exclude JUnit from Jersey with Dependency Exclusions from Maven (like the image below). That way JUnit 4 will not be used anymore, but rather our JUnit 5.
当您运行一些使用Jersey的测试时,它们将不会被加载,因为Jersey中有使用JUnit 4注解的方法,setUp
和tearDown
,使用@Before
和@After
。为了解决这个问题,您可以创建一个“配置类”,它继承自JerseyTest
并实现setUp
和tearDown
,使用@BeforeEach
和@AfterEach
调用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创建,项目不会变成怪物。所以,请记住,保持您的项目更新,因为如果您忘记了库,每一天都会更难更新。始终使用遵循规范的规范和框架,并在您的代码中具有良好的设计,这允许您轻松地进行更改和迁移。
Source:
https://dzone.com/articles/junit-4-5-jupiter-vintage-how-to-deal