首页 > 代码库 > JUnit4学习笔记(二):参数化测试与假定(Assumption)

JUnit4学习笔记(二):参数化测试与假定(Assumption)

一、一个简单的测试

编写一个只有一种运算的计算器:

 

1 public class Calculator {  2     public static double divide(int dividend, int divisor) {  3         return dividend / divisor;  4     }  5 }  

 为这个方法编写测试:

1 public class CalculatorTest {  2     //允许误差  3     private static final double DELTA = 0.01;  4   5     @Test  6     public void testAdd() throws Exception {  7         assertEquals(3, Calculator.divide(9, 3), DELTA);  8     }  9 }  

 这个测试中使用9除以3测试了方法,但是我们希望使用多组数据进行测试,并且不需要编写多个方法,这时候可以使用JUnit的参数化测试。

 

二、参数化测试

在JUnit中,参数化测试有两种形式,第一种形式是构造函数形式,即JUnit遍历所提供的所有参数调用构造函数并执行测试方法:

 1 //使用Parameterized Runner执行参数化测试   2 @RunWith(Parameterized.class)   3 public class CalculatorTest {   4     //允许误差   5     private static final double DELTA = 0.01;   6    7     private int dividend;   8     private int divisor;   9     private int result;  10   11     public CalculatorTest(int dividend, int divisor, int result) {  12         this.dividend = dividend;  13         this.divisor = divisor;  14         this.result = result;  15     }  16   17     // 用@Parameterized.Parameters注解标注该方法是返回所有参数,被注解的方法必须返  18     // 回装载数组的Iterable对象,同时必须为public,static,当测试执行时,系统会遍历  19     // 每组参数(数组)调用构造函数并执行测试。  20     @Parameterized.Parameters  21     public static Iterable<Object[]> getParameters() {  22         return Arrays.asList(new Object[][]{  23                 {9, 3, 3}, {5, 1, 5}, {12, 4, 3}  24         });  25     }  26   27     //当执行测试后,该方法会运行3次  28     @Test  29     public void testDevide throws Exception {  30         assertEquals(result, Calculator.divide(dividend, divisor), DELTA);  31     }  32 }  33  

第二种是变量注入形式,变量的值不通过构造函数初始化,而是通过JUnit注入:

 1 //使用Parameterized Runner执行参数化测试   2 @RunWith(Parameterized.class)   3 public class CalculatorTest {   4     //允许误差   5     private static final double DELTA = 0.01;   6    7     //使用@Parameter标注public变量,JUnit会遍历每组参数进行注入   8     //注解中的整数参数表示注入参数组中的第几个参数   9     @Parameter(0)  10     public int dividend;  11     @Parameter(1)  12     public int divisor;  13     @Parameter(2)  14     public int result;  15   16     // 用@Parameterized.Parameters注解标注该方法是返回所有参数,被注解的方法必须返  17     // 回装载数组的Iterable对象,同时必须为public,static,当测试执行时,系统会遍历  18     // 每组参数(数组)调用构造函数并执行测试。  19     @Parameterized.Parameters  20     public static Iterable<Object[]> getParameters() {  21         return Arrays.asList(new Object[][]{  22                 {9, 3, 3}, {5, 1, 5}, {12, 4, 3}  23         });  24     }  25   26     //当执行测试后,该方法会运行3次  27     @Test  28     public void testDivide() throws Exception {  29         assertEquals(result, Calculator.divide(dividend, divisor), DELTA);  30     }  31 }  

 

三、Assumption

在上面参数化的例子中,如果我们提供的参数为{9, 3, 3}, {15, 0, 0}, {12, 4, 3},那第二组参数则会导致测试失败(15除以0会抛出异常),但是在参数化测试中并不应该使用0为除数作为测试,所以应该是测试数据的问题,不应该导致测试失败。使用org.junit.Assume下的各种assume方法能对测试的数据或者环境做出假设,当这种假设不满足时跳过该测试,这样就可以保证在正确的测试环境下执行测试。

1 @Test  2 public void testDivide() throws Exception {  3     //假定除数不为0,若为0跳过该测试  4     assumeTrue("Divisor can‘t be 0", divisor != 0);  5     assertEquals(result, Calculator.divide(dividend, divisor), DELTA);  6 }  

 使用上述参数执行该测试,第二组参数所对应的测试会被忽略,而不是失败。

此文转载,如有版权限制,愿意自动放弃