在单元测试中,如果测试方法相同,要测试不同的输入参数和输出结果时,通常会有冗余的代码。参数化单元测试的组件,应用在这种场景下。
从JUnit4已经开始支持参数化测试
在测试类上追加@RunWith,指明使用JUnit的Parameterized运行器来运行测试。
在提供数据的方法上追加@Parameterized.Parameters,方法必须是静态static的,并且返回一个集合Collection。
代码如下:
@RunWith(Parameterized.class) public class CalculatorTest { @Parameterized.Parameters public static Collection data() { return Arrays.asList(new Object[][]{{0, 0, 0}, {1, 1, 2}, {2, 1, 3}}); } private int testOpt1; private int testOpt2; private int testResult; private Calculator calculator; public CalculatorTest(int testOpt1, int testOpt2, int testResult) { this.testOpt1 = testOpt1; this.testOpt2 = testOpt2; this.testResult = testResult; } @Before public void setUp() { calculator = new Calculator(); } @Test public void testAdd() throws Exception { int actualResult = calculator.add(testOpt1, testOpt2); assertEquals(testResult, actualResult); } }
再看一下用JUnitParams组建,同样的UT用例的代码量:
@RunWith(JUnitParamsRunner.class) public class CalculatorTestWithJUnitParams { private Calculator calculator; @Before public void setUp() { calculator = new Calculator(); } private Object addTestData() { return new Object[]{ new Object[]{0, 0, 0}, new Object[]{1, 1, 2}, new Object[]{2, 1, 3} }; } @Test @Parameters(method = "addTestData") public void testAdd(int testOpt1, int testOpt2, int testResult) throws Exception { int actualResult = calculator.add(testOpt1, testOpt2); assertEquals(testResult, actualResult); } }
两段代码对比显而易见:
不用通过构造器传递测试参数,用在方法前注解参数内容即可(使用Parameters注解)
测试用例可以指定任意的数据提供方法(使用Parameters里的method)
更简洁的方式:
@RunWith(JUnitParamsRunner.class) public class CalculatorTestWithJUnitParams { private Calculator calculator; @Before public void setUp() { calculator = new Calculator(); } @Test @Parameters({"0, 0, 0", "1, 1, 2", "2, 1, 3"}) public void testAdd(int testOpt1, int testOpt2, int testResult) throws Exception { int actualResult = calculator.add(testOpt1, testOpt2); assertEquals(testResult, actualResult); } }
通过引入import static junitparams.JUnitParamsRunner.$,数据提供方法还可以简化为:
private Object addTestData() { return $( $(0, 0, 0), $(1, 1, 2), $(2, 1, 3) }; }
上面的这些措施 大大简化了测试用例中的重复代码。
maven:
<dependency> <groupId>pl.pragmatists</groupId> <artifactId>JUnitParams</artifactId> <version>1.0.4</version> <scope>test</scope> </dependency>
更高级的使用场景,可以参考:
JUnitParams例子:
https://github.com/Pragmatists/JUnitParams/blob/master/src/test/java/junitparams/usage/Samples_of_Usage_Test.java