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 }  

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

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

posted @ 2014-08-04 16:47  johnson1018  阅读(320)  评论(0编辑  收藏  举报