一、一个简单的测试
编写一个只有一种运算的计算器:
- public class Calculator {
- public static double divide(int dividend, int divisor) {
- return dividend / divisor;
- }
- }
为这个方法编写测试:
- public class CalculatorTest {
- //允许误差
- private static final double DELTA = 0.01;
- @Test
- public void testAdd() throws Exception {
- assertEquals(3, Calculator.divide(9, 3), DELTA);
- }
- }
这个测试中使用9除以3测试了方法,但是我们希望使用多组数据进行测试,并且不需要编写多个方法,这时候可以使用JUnit的参数化测试。
二、参数化测试
在JUnit中,参数化测试有两种形式,第一种形式是构造函数形式,即JUnit遍历所提供的所有参数调用构造函数并执行测试方法:
- //使用Parameterized Runner执行参数化测试
- @RunWith(Parameterized.class)
- public class CalculatorTest {
- //允许误差
- private static final double DELTA = 0.01;
- private int dividend;
- private int divisor;
- private int result;
- public CalculatorTest(int dividend, int divisor, int result) {
- this.dividend = dividend;
- this.divisor = divisor;
- this.result = result;
- }
- // 用@Parameterized.Parameters注解标注该方法是返回所有参数,被注解的方法必须返
- // 回装载数组的Iterable对象,同时必须为public,static,当测试执行时,系统会遍历
- // 每组参数(数组)调用构造函数并执行测试。
- @Parameterized.Parameters
- public static Iterable<Object[]> getParameters() {
- return Arrays.asList(new Object[][]{
- {9, 3, 3}, {5, 1, 5}, {12, 4, 3}
- });
- }
- //当执行测试后,该方法会运行3次
- @Test
- public void testDevide throws Exception {
- assertEquals(result, Calculator.divide(dividend, divisor), DELTA);
- }
- }
第二种是变量注入形式,变量的值不通过构造函数初始化,而是通过JUnit注入:
- //使用Parameterized Runner执行参数化测试
- @RunWith(Parameterized.class)
- public class CalculatorTest {
- //允许误差
- private static final double DELTA = 0.01;
- //使用@Parameter标注public变量,JUnit会遍历每组参数进行注入
- //注解中的整数参数表示注入参数组中的第几个参数
- @Parameter(0)
- public int dividend;
- @Parameter(1)
- public int divisor;
- @Parameter(2)
- public int result;
- // 用@Parameterized.Parameters注解标注该方法是返回所有参数,被注解的方法必须返
- // 回装载数组的Iterable对象,同时必须为public,static,当测试执行时,系统会遍历
- // 每组参数(数组)调用构造函数并执行测试。
- @Parameterized.Parameters
- public static Iterable<Object[]> getParameters() {
- return Arrays.asList(new Object[][]{
- {9, 3, 3}, {5, 1, 5}, {12, 4, 3}
- });
- }
- //当执行测试后,该方法会运行3次
- @Test
- public void testDivide() throws Exception {
- assertEquals(result, Calculator.divide(dividend, divisor), DELTA);
- }
- }
三、Assumption
在上面参数化的例子中,如果我们提供的参数为{9, 3, 3}, {15, 0, 0}, {12, 4, 3},那第二组参数则会导致测试失败(15除以0会抛出异常),但是在参数化测试中并不应该使用0为除数作为测试,所以应该是测试数据的问题,不应该导致测试失败。使用org.junit.Assume下的各种assume方法能对测试的数据或者环境做出假设,当这种假设不满足时跳过该测试,这样就可以保证在正确的测试环境下执行测试。
- @Test
- public void testDivide() throws Exception {
- //假定除数不为0,若为0跳过该测试
- assumeTrue("Divisor can't be 0", divisor != 0);
- assertEquals(result, Calculator.divide(dividend, divisor), DELTA);
- }
使用上述参数执行该测试,第二组参数所对应的测试会被忽略,而不是失败。
原文链接:http://haibin369.iteye.com/blog/2078535