在JUnit4中使用参数化测试时,是否有一种方法可以设置我自己的自定义测试用例名称?

我想改变默认的-[测试类]. runtest [n] -有意义的东西。


当前回答

当您想要测试名称中的参数值时,您可以执行类似于-的操作

@ParameterizedTest(name="{index} {arguments} then return false" )
@ValueSource(strings = {"false","FALSE","   ","123","abc"})
@DisplayName("When Feature JVM argument is ")
void test_Feature_JVM_Argument_Is_Empty_Or_Blank_Strings_Or_False(String params) {
    System.setProperty("FeatureName", params);
    assertFalse(Boolean.parseBoolean(System.getProperty("FeatureName")));
}

测试名称看起来像-

JUnit测试图像

其他回答

这个特性已经加入到JUnit 4.11中。

若要使用更改参数化测试的名称,请执行以下命令:

@Parameters(name="namestring")

Namestring是一个字符串,可以有以下特殊占位符:

{index} -这组参数的索引。默认名称字符串是{index}。 {0} -测试调用的第一个参数值。 {1} -第二个参数值 等等

测试的最终名称将是测试方法的名称,后面跟着括号中的名称字符串,如下所示。

例如(改编自Parameterized注释的单元测试):

@RunWith(Parameterized.class)
static public class FibonacciTest {

    @Parameters( name = "{index}: fib({0})={1}" )
    public static Iterable<Object[]> data() {
        return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 },
                { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } });
    }

    private final int fInput;
    private final int fExpected;

    public FibonacciTest(int input, int expected) {
        fInput= input;
        fExpected= expected;
    }

    @Test
    public void testFib() {
        assertEquals(fExpected, fib(fInput));
    }

    private int fib(int x) {
        // TODO: actually calculate Fibonacci numbers
        return 0;
    }
}

将给出像testFib[1: fib(1)=1]和testFib[4: fib(4)=3]这样的名称。(名称的testFib部分是@Test的方法名)。

查看dsaff提到的JUnitParams,它使用ant在html报告中构建参数化测试方法描述。

这是在尝试LabelledParameterized并发现它虽然可以与eclipse一起工作,但就html报告而言,它不能与ant一起工作。

欢呼,

一种解决方法是捕获所有Throwable并将其嵌套到一个新的Throwable中,并使用包含有关参数的所有信息的自定义消息。消息将出现在堆栈跟踪中。 当所有断言、错误和异常的测试失败时,这种方法都有效,因为它们都是Throwable的子类。

我的代码是这样的:

@RunWith(Parameterized.class)
public class ParameterizedTest {

    int parameter;

    public ParameterizedTest(int parameter) {
        super();
        this.parameter = parameter;
    }

    @Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] { {1}, {2} });
    }

    @Test
    public void test() throws Throwable {
        try {
            assertTrue(parameter%2==0);
        }
        catch(Throwable thrown) {
            throw new Throwable("parameter="+parameter, thrown);
        }
    }

}

失败测试的堆栈跟踪是:

java.lang.Throwable: parameter=1
    at sample.ParameterizedTest.test(ParameterizedTest.java:34)
Caused by: java.lang.AssertionError
    at org.junit.Assert.fail(Assert.java:92)
    at org.junit.Assert.assertTrue(Assert.java:43)
    at org.junit.Assert.assertTrue(Assert.java:54)
    at sample.ParameterizedTest.test(ParameterizedTest.java:31)
    ... 31 more

对于一个更复杂的对象,您可以执行以下操作(以JUnit 4为例):

@RunWith(Parameterized.class)
public class MainTest {
    private static Object[] makeSample(String[] array, int expectedLength) {
        return new Object[]{array, expectedLength, Arrays.toString(array)};
    }

    @Parameterized.Parameters(name = "for input {2} length should equal {1}")
    public static Collection<Object[]> data() {
        return Arrays.asList(
                makeSample(new String[]{"a"}, 1),
                makeSample(new String[]{"a", "b"}, 2)
        );
    }
    private final int expectedLength;
    private final String[] array;

    public MainTest(String[] array, int expectedLength, String strArray) {
        this.array = array;
        this.expectedLength = expectedLength;
    }

    @Test
    public void should_have_expected_length() {
        assertEquals(expectedLength, array.length);
    }
}

这里的技巧是使用一个输入参数作为字符串来描述输入的某些部分或整个测试用例。

在添加第三个参数之前,它是这样的

然后像这样

看看JUnit 4.5,它的运行器显然不支持这一点,因为该逻辑隐藏在Parameterized类中的私有类中。您不能使用JUnit Parameterized运行器,而是创建自己的能够理解名称概念的运行器(这导致了如何设置名称的问题……)

从JUnit的角度来看,如果他们传递逗号分隔的参数,而不是(或除了)仅仅传递一个增量,那就更好了。TestNG就是这样做的。如果这个特性对你很重要,你可以在www.junit.org的雅虎邮件列表上发表评论。