JUnitParams - 在测试前执行单独的方法

JUnitParams - executing separate methods before test

@RunWith(JUnitParamsRunner.class)
public class MySimpleTest {

    private MyRec rec;
    private Matrix matrix;

    @Before
    public void createRecognizerBeforeEveryExecution() {
        rec = new MyRec();
        matrix = MatrixUtils.createMatrixWithValues();
    }

    public static Iterable<Object[]> data() {
        return Arrays.asList(
                new Object[]{"expectedvalue1", "input1"},
                new Object[]{"expectedvalue2", "input2"}
        );
    }

    @Test
    @Parameters(method = "data")
    public void test1(String output, String input) {
        rec.fun1(matrix);
        assertEquals(output, rec.someFunction(input));
    }

    public static Iterable<Object[]> data2() {
        return Arrays.asList(
                new Object[]{"expectedothervalue1", "input1"},
                new Object[]{"expectedothervalue2", "input2"}
        );
    }

    @Test
    @Parameters(method = "data2")
    public void test2(String output, String input) {
        rec.fun1(matrix);
        rec.fun2(matrix);
        assertEquals(output, rec.someFunction(input));
    }

}

我正在尝试找出进行此测试的正确方法。我想使用参数化测试,因为它真的很方便。

正如您所见,在每个测试函数中我都调用了一些函数(fun1fun2)。但是我每次测试只需要调用一次(例如,在每次参数化测试执行之前)。

有什么方法可以告诉 JUnitParams 它应该在执行所有参数化测试之前执行其他函数吗?

我不能使用 @Before 注释,因为正如您在 test1 中看到的那样,我没有使用 fun2。它认为它应该由单独的函数执行。

解决方案一:

由于 fun[1|2] 不依赖于内部测试状态,因此尝试将它们的调用相应地放置在 data 和 data2 方法中。

public static Iterable<Object[]> data() {
        rec.fun1(matrix);
        return Arrays.asList(
                new Object[]{"expectedvalue1", "input1"},
                new Object[]{"expectedvalue2", "input2"}
        );
    }

public static Iterable<Object[]> data2() {
        rec.fun1(matrix);
        rec.fun2(matrix);
        return Arrays.asList(
                new Object[]{"expectedvalue1", "input1"},
                new Object[]{"expectedvalue2", "input2"}
        );
    }

方案二:

拆分测试用例不是最佳做法。您的测试更难维护。流程要复杂得多。您的测试开始也存在相互依赖的风险。有时重复测试会更好。

PS: 如果您使用字符串作为测试方法参数,最好完全按照此文件第 25 行的方式传递它们: https://github.com/Pragmatists/JUnitParams/blob/master/src/test/java/junitparams/usage/SamplesOfUsageTest.java 而不是特殊方法。

@Test
@Parameters({"AAA,1", "BBB,2"})
public void paramsInAnnotation(String p1, Integer p2) { }

我决定使用TestNG来解决这个问题(代码只是为了展示我的思路):

import org.testng.Assert;
import org.testng.annotations.*;

import java.lang.reflect.Method;

public class TempTest {

    private Integer number;

    @BeforeMethod
    public void init(Method m) {
        number = 5;
        switch(m.getName()) {
            case "test2":
                fun(10);
                fun2(5);
                break;
            case "test1":
                fun(10);
                break;
        }
    }

    public void fun(int value) {
        number += value;
    }

    public void fun2(int value) {
        number -= value;
    }

    @Test
    public void test1() {
        Assert.assertEquals(new Integer(15), number);
    }

    @Test
    public void test2() {
        Assert.assertEquals(new Integer(10), number);
    }

    @Test
    public void test3() {
        Assert.assertEquals(new Integer(5), number);
    }

}