Как подготовить и предоставить тестовые данные

Я пытаюсь написать тестовый пример (используя 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;
    }
}

Из этого ответа /questions/36714486/napisanie-testov-java-s-postavschikami-dannyih/36714488#36714488 я безуспешно пытался что-то вроде,

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);
    }
}

когда я запускаю это, я получаю сообщение об ошибке "У метода test не должно быть параметров".

Вот мои вопросы:

  1. Как можно написать контрольный пример для такой ситуации?
  2. Как я могу подготовить данные для теста?
  3. Можем ли мы создать файл, похожий на файл свойств, типа файла в папке ресурсов, чтобы он мог быть предоставлен и для другой функции.

2 ответа

Решение

Похоже, что тестируемая функция принимает двумерный массив и возвращает целое число, и вам необходимо проверить, является ли возвращенное значение правильным или нет. У меня есть аналогичный код и тестовый модуль с использованием 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));
    }
}

Убедитесь, что вы импортируете правильные библиотеки для JUnit в eclipse. Сделайте так, чтобы ваш класс тестового примера соответствовал моему, и вы должны быть готовы. Надеюсь это поможет.

Я нахожу такой подход, как правило, весьма неприятным для вариантов использования, подобных вашему, особенно потому, что он не является необходимым и усложняет чтение и понимание теста.

Почему это не нужно? Если я пишу метод, который суммирует два целых числа, и я тестирую 1 + 2 = 3, зачем мне нужно писать другой тест, который гарантирует, что 2 + 2 = 4? Вы можете задать себе следующие вопросы: "Что мне нужно изменить в моем коде, чтобы второй тест (2+2=4) не прошел, но первый тест все равно прошел?" Если я могу изменить производственный код, то второй сбой, но первый нет, это означает, что обычно это два отдельных теста.

Почему это сложнее понять? Один блок

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)
}

Если тест не пройден, у меня есть вся информация в нескольких строках кода. Во-вторых, вы не знаете, какие параметры использовались, определение параметров может быть где-то в вашем тестовом классе, поэтому вы тратите больше времени, чтобы фактически выяснить, в чем проблема.

Другие вопросы по тегам