当前位置: 首页 > 知识库问答 >
问题:

具有多个测试的参数化junit测试

莫英卓
2023-03-14

参数化测试可以将不同的数据输入到测试中。不过,我创建了一个示例计算器,希望为其创建参数化测试。但是,我发现您只能为单个测试创建一组参数化数据。

我已经创建了参数化测试,用于添加两个数字,得到预期的结果。由于预期结果会有所不同,因此该数据将不适用于减法运算。

有没有可能为每个加、减、乘、除测试提供参数化数据?

非常感谢您的建议,

@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;
    }
}

共有3个答案

齐鹏程
2023-03-14

只需添加另一个参数如下:

 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);
}
阎经武
2023-03-14

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

傅胡媚
2023-03-14

您可以为每个测试编写一个内部类,每个测试都有一组不同的参数,并使用附带的运行程序运行它。

@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 runner。

@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);
    } 
}
 类似资料:
  • 问题内容: 在我们的项目中,我有几个JUnit测试,例如从目录中获取每个文件并对其进行测试。如果我在中实现了一种方法,那么它只会显示为可能失败或成功的一项测试。但是我对每个文件的结果都很感兴趣。如何编写一个/ 使得每个文件显示为单独的测试,例如在Eclipse的图形TestRunner中?(为每个文件编写显式测试方法不是一种选择。) 问题答案: 看看JUnit 4 中的 参数化测试 。 实际上,我

  • 我试图定义一个,如示例MockitoExtension所提供的,但无法成功地使用参数化的类实例。 期待着关于如何用在中实现接口的类的参数化实例测试接口的建议。

  • 下面是这个问题:我被要求从哪里开始一个新问题。 问题是我对JUnit了解不够,或者对等的了解不够,无法以Jeff Bowman提到的方式解决这个问题。

  • 问题内容: 我有一系列要在电子商务平台上测试的商店,并且每个商店都具有要针对其自动化测试的一系列属性。是否可以有一个数据提供程序在整个测试套件中提供数据,而不仅仅是在TestNG中提供测试?我试图不使用testNG.xml文件作为机制,因为这些属性直接来自数据库调用。 我需要自动执行以下操作: @Test在当前数据集行中使用用户名和密码登录。 @Test验证StoreName和items-stor

  • 问题内容: 我有一个junit测试,它产生了50个测试: 运行它需要一个小时(并且不可能缩短时间,它们是集成测试)。测试28失败。 如何单独运行测试28,而不运行其他49个测试?只需更改IntelliJ(或Eclipse)运行配置中的或类似内容,而无需更改实际代码。 问题答案: Eclipse现在(从Mars M4版本开始)不仅可以运行Parameterized测试类中的单个测试,还可以运行任何类

  • 我有一个junit测试testArchive()。Junit测试测试存档文件并将url作为字符串返回给它的archive()方法。URL被定义为Junit测试类中的实例变量。 我正在为sendEmail()编写另一个Junit测试,它通过电子邮件发送URL。但是URL被定义为一个类变量,结果却是空的 你能让我知道我需要如何修正我的Junit测试发送电子邮件吗? 谢谢你