JUnit Jupiter (JUnit5) 中的参数化测试执行

Parameterised Test Execution in JUnit Jupiter(JUnit5)

有没有办法在 JUnit Jupiter (Junit5) 中进行参数化测试?

@RunWith(Parameterized.class)

背景:

我使用 JUnit5 完成了 How to write junit tests for interfaces? and wanted to implement test cases as answered here。但是在 Jupiter 包中找不到相同的 class/es。

尝试次数:

进一步寻找替代品,我发现 Extensions would be replacing the @RunWith as stated in Migrating tips

@RunWith no longer exists; superseded by @ExtendWith.

我尝试定义示例 here - MockitoExtension 中提供的 CustomExtension,但无法成功使用 类 Parameterized[=36] 的实例=].

期待关于如何使用 类 在 JUnit5 中实现它的参数化实例测试接口的建议。

自 2017 年 1 月 9 日起,JUnit 5 本身不支持参数化测试,但会处理该功能 is in progress. Note that you might be able to achieve something similar with dynamic tests

也就是说,我会考虑实现接口测试的两种不好的方法,而 JUnit Jupiter 提供了两种更好的方法:

  1. @Test 注释接口默认方法 will be executed。因此,如果您有一个生产接口 Interface,您可以编写一个接口 InterfaceTest,它使用默认方法来测试您想要的一切。对于每个 Impl implements Interface 你可以写一个 ImplTest implements InterfaceTest.
  2. 如果您需要更大的灵活性,并希望在抽象 class AbstractInterfaceTest 中实现 Interface 的测试,您也可以这样做,然后 nested test class 在你的 ImplTest 中延伸 AbstractInterfaceTest.

这两种方法都确保接口测试不知道实现接口的 classes,这是 answer you linked to 的一个巨大缺点。

在我的项目中,我一直在使用这个库:

https://github.com/TNG/junit-dataprovider/

以便将参数化添加到我的 JUnit 测试中。 我一直在使用 4.x 版本,但从来不喜欢它提供的嵌入式参数化。 如果您熟悉 TestNg 的 @DataProvider,那么这个扩展并没有太大的不同。

检查一下,看看它是否对您有任何好处,就像对我和我的团队一样。坦率地说,我现在无法想象没有它的工作。

你可以使用 dynamic tests

@TestFactory
Stream<DynamicTest> params() {

        return Stream.of(new double[][]{{2d, 4d}, {3d, 9d}, {4d, 16d}}).
                map(i ->
                        dynamicTest("Square root test " + Arrays.toString(i),
                                () -> assertEquals(i[0], Math.sqrt(i[1]))
                        )
                );
}

JUnit 5 M4 刚刚发布,现在支持参数化测试。

这是 "Hello World" 示例:

@ParameterizedTest
@ValueSource(strings = { "Hello", "World" })
void testWithStringParameter(String argument) {
    assertNotNull(argument);
}

请参阅 User Guide 以获取完整文档和其他示例。