如何测试不良参数的所有组合?

时间:2016-06-01 11:33:54

标签: java exception junit

让我们假设一个抛出IndexOutOfBoundsException的简单方法 对于一对无效的索引(2d数组)。

我将如何测试,所有错误组合都会引发异常 指数?

(当然,如果这个测试不会继续 一个电话会抛出异常)

@Test(expected = Exception.class)
public void validateIndices(){
    check(0,-1);
    check(-1,0);
    check(0,COLS + 1);
    check(ROWS + 1, 0);
}

是否有一种常用的测试方法 方法参数的变化?

4 个答案:

答案 0 :(得分:7)

除了@Nicolas_Filot回答之外,您还可以使用Junit Theories。它更具可读性,与Parameterized不同,它将使用所有可能的参数组合执行测试。

@RunWith(Theories.class)
public class MyTest {
    @DataPoints("cols")
    public static int[] rowValues(){
        return new int[]{0, -1, 1, 2};
    }
    @DataPoints("rows")
    public static int[] colValues(){
        return new int[]{0, -1, 4, 5};
    }

    @Theory
    public void upperBoundIsChecked(@FromDataPoints("cols") int col,
                                    @FromDataPoints("rows") int row){
        assumeTrue(row >= ROWS || col >= COLS);
        try {
            check(col, row);
            fail("Should have thrown IllegalArgumentException");
        } catch (IllegalArgumentException ignore){}
    }

    @Theory
    public void lowerBoundIsChecked(@FromDataPoints("cols") int col,
                                    @FromDataPoints("rows") int row){
        assumeTrue(row < 0 || col < 0);
        try {
            check(col, row);
            fail("Should have thrown IllegalArgumentException");
        } catch (IllegalArgumentException ignore){}
    }

    @Theory
    public void validIndicesNoException(@FromDataPoints("cols") int col,
                                        @FromDataPoints("rows") int row){
        assumeTrue(row >= 0 && col >= 0 && row < ROWS && col < COLS);
        try {
            check(col, row);
        } catch (Exception e){
            fail("Should not have thrown an exception: " + e.getMessage());
        }
    }

}

每个理论都将检查符合理论假设的行和列的所有可能组合。

或者,如果您的列和行列表相同,则可以更轻松地完成:

@RunWith(Theories.class)
public class MyTest {

   @DataPoints
   public static int[] values(){
      return new int[]{0, -1};
   }
   @Theory
   public void validateIndices(int col, int row){
      check(col,row);
   }
}

答案 1 :(得分:6)

在您的情况下,我会Parameterized我的单元测试来测试所有具有相同测试的组合更多信息here

在你的情况下,它看起来像这样:

@RunWith(Parameterized.class)
public class MyTest {
    @Parameterized.Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] {
            { 0, -1 }, { -1, 0 }
        });
    }

    @Parameterized.Parameter
    public int row;

    @Parameterized.Parameter(value = 1)
    public int col;

    @Test(expected = IndexOutOfBoundsException.class)
    public void validateIndices(){
        check(row, col);
    }
}

答案 2 :(得分:2)

其他答案当然是正确的,因为他们做了你想要的,但他们有一个很大的概念缺点:他们只能检查错误条件......你必须手动指定。

含义:这种测试只能证明您正在测试的代码&#34;为那些明确定义的案例做了预期的事情。

将它与您告诉环境的编程模型进行比较:&#34;这就是我期望我的函数表现的方式&#34 ;;然后该环境试图找到您的函数中断的输入。

如果这听起来很有趣,你应该看看QuickCheck。虽然不是真的&#34;本地&#34;对Java而言,绝对不是#34;主流&#34;截至目前......值得一试。

答案 3 :(得分:0)

好吧,如果索引都是Integer值,则可以使用try-catch语句进行for循环:

for (int i = iBegin; i < iEnd; i++) {
  for (int j = jBegin; j < jEnd; j++) {
    try { check(i, j); }
    catch (Exception e) { iList.add(i); jList.add(j); }
  }
}

(iList和jList在这种情况下是某种类型的Collection; iBegin,jBegin,iEnd和jEnd是Integer值,它们给出变化的边界)