Как подготовить и предоставить тестовые данные
Я пытаюсь написать тестовый пример (используя 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 не должно быть параметров".
Вот мои вопросы:
- Как можно написать контрольный пример для такой ситуации?
- Как я могу подготовить данные для теста?
- Можем ли мы создать файл, похожий на файл свойств, типа файла в папке ресурсов, чтобы он мог быть предоставлен и для другой функции.
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)
}
Если тест не пройден, у меня есть вся информация в нескольких строках кода. Во-вторых, вы не знаете, какие параметры использовались, определение параметров может быть где-то в вашем тестовом классе, поэтому вы тратите больше времени, чтобы фактически выяснить, в чем проблема.