使用多个测试的参数化JUnit测试

5

参数化测试有助于将不同的数据输入到您的测试中。然而,我创建了一个简单的计算器,并希望为其创建参数化测试。但是我发现,在单个测试中只能创建一个参数化数据集。

我已经为加法创建了一个带有预期结果的参数化测试。但是这些数据无法用于减法,因为预期结果将不同。

是否可能为每个加法、减法、乘法和除法的测试都创建参数化数据?

非常感谢您的任何建议,

@RunWith(Parameterized.class)
public class CalculatorModelPresenterTest {

    private CalculatorModel mCalculatorModel;

    /* Array of tests */
    @Parameterized.Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][]{
                {3.0, 4.0, 7.0},
                {4.0, 3.0, 7.0},
                {8.0, 2.0, 10.0},
                {-1.0, 4.0, 3.0},
                {3256.0, 4.0, 3260.0}
        });
    }

    private double mNumberOne;
    private double mNumberTwo;
    private double mExpectedResult;

    /* CONSTRUCTOR THAT ASSIGNS THE FIELDS WITH THE TEST DATA */
    public CalculatorModelPresenterTest(double numberOne, double numberTwo, double expectedResult) {
        mNumberOne = numberOne;
        mNumberTwo = numberTwo;
        mExpectedResult = expectedResult;
    }

    /* THIS TEST WILL PASS AS THE TEST DATA IS FOR ADDING */
    @Test
    public void testAdd() throws Exception {
        final double actualResult = mCalculatorModel.add(mNumberOne, mNumberTwo);
        assertEquals(actualResult, mExpectedResult, 0);
    }

    /* HOWEVER, THIS TEST WILL ALWAYS FAIL AS THE TEST DATA IS CUSTOMIZED FOR THE ADD */
    @Test
    public void testSub() throws Exception {
        final double actualResult = mCalculatorModel.sub(mNumberOne, mNumberTwo);
        assertEquals(actualResult, mExpectedResult, 0);
    }

    @Before
    public void setUp() throws Exception {
        mCalculatorModel = new CalculatorModel();
    }

    @After
    public void tearDown() throws Exception {
        mCalculatorModel = null;
    }
}

1
你不需要在tearDown方法中将mCalculatorModel设置为null,因为JUnit会为每组参数创建一个CalculatorModelPresenterTest类的新实例。 - Stefan Birkner
3个回答

10

你可以为每个测试编写一个内部类,每个内部类具有不同的参数集,并使用Enclosed runner运行它。

@RunWith(Enclosed.class)
public class CalculatorModelPresenterTest {

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

        @Parameterized.Parameters
        public static Object[][] data() {
            return new Object[][]{
                {3.0, 4.0, 7.0},
                {4.0, 3.0, 7.0},
                {8.0, 2.0, 10.0},
                {-1.0, 4.0, 3.0},
                {3256.0, 4.0, 3260.0}
            };
        }

        @Parameterized.Parameter(0)
        private double mNumberOne;
        @Parameterized.Parameter(1)
        private double mNumberTwo;
        @Parameterized.Parameter(2)
        private double mExpectedResult;

        @Test
        public void testAdd() throws Exception {
            CalculatorModel calculatorModel = new CalculatorModel();
            double actualResult = calculatorModel.add(mNumberOne, mNumberTwo);
            assertEquals(actualResult, mExpectedResult, 0);
        }
    }   

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

        @Parameterized.Parameters
        public static Object[][] data() {
            return new Object[][]{
                {3.0, 4.0, -1.0},
                {4.0, 3.0, 1.0},
                {8.0, 2.0, 6.0},
                {-1.0, 4.0, -5.0},
                {3256.0, 4.0, 3252.0}
            };
        }

        @Parameterized.Parameter(0)
        private double mNumberOne;
        @Parameterized.Parameter(1)
        private double mNumberTwo;
        @Parameterized.Parameter(2)
        private double mExpectedResult;

        @Test
        public void testSub() throws Exception {
            CalculatorModel calculatorModel = new CalculatorModel();
            double actualResult = calculatorModel.sub(mNumberOne, mNumberTwo);
            assertEquals(actualResult, mExpectedResult, 0);
        }
    } 
}

另一种方法是使用JUnitParams运行器。

@RunWith(JUnitParamsRunner.class)
public class CalculatorModelPresenterTest {

    @Test
    @Parameters({
            "3.0, 4.0, 7.0",
            "4.0, 3.0, 7.0",
            "8.0, 2.0, 10.0",
            "-1.0, 4.0, 3.0",
            "3256.0, 4.0, 3260.0" })
    public void testAdd(double first, double second, double expectedResult)
            throws Exception {
        CalculatorModel calculatorModel = new CalculatorModel();
        double actualResult = calculatorModel.add(first, second);
        assertEquals(actualResult, expectedResult, 0);
    }   

    @Test
    @Parameters({
            "3.0, 4.0, -1.0",
            "4.0, 3.0, 1.0",
            "8.0, 2.0, 6.0",
            "-1.0, 4.0, -5.0",
            "3256.0, 4.0, 3252.0" })
    public void testSub(double first, double second, double expectedResult)
            throws Exception {
        CalculatorModel calculatorModel = new CalculatorModel();
        double actualResult = calculatorModel.sub(first, second);
        assertEquals(actualResult, expectedResult, 0);
    } 
}

3

使用JUnit 4时,您不能拥有多个@Parameters方法。您需要为每个带有新参数的操作添加一个新类。


那正是我所想的,但我不想为了进行一些简单的测试而不断添加类。 - ant2009

1
只需像这样添加另一个参数:

 return Arrays.asList(new Object[][]{
            {3.0, 4.0, 7.0, -1.0},
            {4.0, 3.0, 7.0, 1.0},
            {8.0, 2.0, 10.0, 6.0},
            {-1.0, 4.0, 3.0, -5.0},
            {3256.0, 4.0, 3260.0, 3252.0}
    });

...

private double mExpectedSubResult;

/* CONSTRUCTOR THAT ASSIGNS THE FIELDS WITH THE TEST DATA */
public CalculatorModelPresenterTest(double numberOne, double numberTwo, double expectedResult, double expectedSubResult) {
    mNumberOne = numberOne;
    mNumberTwo = numberTwo;
    mExpectedResult = expectedResult;
    mExpectedSubResult = expectedSubResult;
}
...

/* THIS TEST WILL NOW PASS */
@Test
public void testSub() throws Exception {
    final double actualResult = mCalculatorModel.sub(mNumberOne, mNumberTwo);
    assertEquals(actualResult, mExpectedSubResult, 0);
}

好的。只需要将参数不断添加到数组中即可。谢谢。 - ant2009

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接