JUnit,4,5,Jupiter,Vintage

自从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:

Java

 

@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注解的方法,setUptearDown,使用@Before@After。为了解决这个问题,您可以创建一个“配置类”,它继承自JerseyTest并实现setUptearDown,使用@BeforeEach@AfterEach调用super.setUp()super.TearDown()

Java

 

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