如何准备和提供测试数据

时间:2017-04-13 16:55:30

标签: java eclipse unit-testing junit test-data

我正在尝试编写一个测试用例(使用Java,Maven,Junit,Eclipse)来计算矩阵对角线总和差异的小函数。

要测试的功能

    public static int diagonalDifference(Integer matrix[][], int n) {
        int diagonalSum1 = 0;
        int diagonalSum2 = 0;
        int diagonalDifference = 0;

        for (int i = 0; i < n; i++) {
            diagonalSum1 = diagonalSum1 + matrix[i][i];
            diagonalSum2 = diagonalSum2 + matrix[i][Math.abs(i - 2)];
        }

        diagonalDifference = Math.abs(diagonalSum1 - diagonalSum2);
        return diagonalDifference;
    }
}

从这个答案https://stackoverflow.com/a/19349565/7115684我没有成功尝试类似的事情,

public class testSolutions {

    Solution solution = new Solution();

    Integer a[][] = { { 11, 2, 4 }, { 4, 5, 6 }, { 10, 8, -12 } };
    Integer b[][] = { { 12, 22, 8 }, { 2, 16, 8 }, { 10, 5, -1 } };

    @DataProvider
    public Object[][] provideMatrixAndExpectedSum() {
         return new Object[][] { { a, new Integer(15) } };
    }

    @Test
    @UseDataProvider("provideMatrixAndExpectedSum")
    public void test(Integer a[][], int n) {

        int diagonalDifference = Solution.diagonalDifference(a, n);

        assertEquals(diagonalDifference, 15);
    }
}

当我运行时,我收到错误&#34;方法测试应该没有参数。&#34;

我的问题是:

  1. 如何针对这种情况编写测试用例?
  2. 我如何准备测试数据?
  3. 我们可以在资源文件夹中创建类似属性类型的文件,以便它也可以提供给其他函数。

2 个答案:

答案 0 :(得分:1)

似乎要测试的函数接受2d数组并返回一个整数,您需要测试返回的值是否正确。 我有一个使用JUint的类似代码和测试单元。不要打扰我的代码所做的事情,只关注传递的输入和要验证的输出。

public class countUniqueNums {

public int countUnique (int[] nums) {
    int unique=0;
    int [] intVal = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    for (int i = 0; i<nums.length; i++) {
        intVal[nums[i]+9]++;
        if (intVal[nums[i]+9]==1)
            unique++;
        else
            if (intVal[nums[i]+9]==2)
                unique--;
    }
    return unique;
 }
}

测试单位如下:

import static junitparams.JUnitParamsRunner.$;
import static org.junit.Assert.assertEquals;    
import org.junit.Test;
import org.junit.runner.RunWith;    
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;

@RunWith(JUnitParamsRunner.class)
public class countUniqueNumsParamTest {

    @SuppressWarnings({ "unused", "deprecation" })
    private static final Object[] countUniqueNumbers () {
        return $(
                // Parameters are (1,2),  1=expected result count, 2= input array
                    $(1,new int[]{0}),      //Test Case 1
                    $(0,new int[]{}),       //Test Case 2
                    $(0,new int[]{0,0}),    //Test Case 3           
                    $(0,new int[]{0,0,0}),  //Test Case 4

                    $(1,new int[]{0,1,1,1}),    //Test Case 5
                    $(1,new int[]{1,1,1,0}),    //Test Case 6
                    $(2,new int[]{1,0,2,1}),    //Test Case 7
                    $(4,new int[]{0,1,2,3})     //Test Case 8

                    );
    }
    @Test
    @Parameters(method="countUniqueNumbers")
    public void test(int unique, int[] nums) {
        countUniqueNums cun = new countUniqueNums();
        assertEquals(unique, cun.countUnique(nums));
    }
}

确保在eclipse中为JUnit导入正确的库。定制你的测试用例类以匹配我的,你应该很高兴去。 希望这会有所帮助。

答案 1 :(得分:0)

我发现这种方法通常会对像您这样的用例感到非常不安,特别是因为它不是必需的,并且使得阅读和理解测试变得更加困难。

为什么没有必要?如果我编写一个总结两个整数的方法并且我测试1 + 2 = 3,为什么我需要编写另一个测试来确保2 + 2 = 4?您可以问自己的问题是,&#34; 我需要在代码中更改,以便第二次测试(2 + 2 = 4)失败第一次测试仍然通过?&#34;如果我可以更改生产代码,那么第二个会失败,但第一个不会,这意味着它通常是两个单独的测试。

为什么难以理解? 一块

int summand1 = 1;
int summand2 = 2;

int sum = MyMath.sum(summand1, summand2);

assertEquals(3, sum);

更容易理解
public void myTest(int summand1, int summand2, int expectedResult) {
   int sum = MyMath.sum(summand1, summand2);

   assertEquals(expectedResult, sum)
}

如果测试失败,我会在几行代码中获得所有信息。对于第二个,您不知道使用了哪些参数,参数的定义可以在您的测试类中的某个位置,因此您可以使用更多时间来实际找出问题所在。