Как сгенерировать метод нескольких тестов из JSON? - PullRequest
0 голосов
/ 12 марта 2020

У меня есть огромный JSON -файл, который содержит тестовые случаи. (Нет, я не хочу показывать это здесь, потому что в данном случае не имеет значения знать файл). Я анализирую файл json в своем тесте junit - это прекрасно работает. Но у меня есть 50 тестовых случаев, и если я хочу показать каждый в Junit как: «тест 0 из 50 пройден», и у меня есть список вроде: тест 1 пройден, тест 2 пройден, тест 3 не пройден ..

Я должен поместить каждый тестовый пример в метод. Как я могу динамически сделать это? Возможно ли это в Junit? Потому что, когда я анализирую json, я не знаю, сколько у меня дел.

1 Ответ

1 голос
/ 12 марта 2020

JUnit имеет прямую поддержку файлов CSV, что означает, что вы можете легко импортировать и использовать их, используя @CSVFileSource.

Однако, поскольку в вашем случае не используются файлы CSV, я попытался создать параметризованные тесты в JUnit 5 с использованием JSON файлов.

Наш тестируемый класс.

public class MathClass {
    public static int add(int a, int b) {
        return a + b;
    }
}

Вот файл JSON, который я использую.

[
  {
    "name": "add positive numbers",
    "cases": [[1, 1, 2],[2, 2, 4]]
  },
  {
    "name": "add negative numbers",
    "cases": [[-1, -1, -2 ], [-10, -10, -20 ]]
  }
]

Итак, в JUnit 5 есть аннотация под названием @MethodSource, которая дает вам возможность предоставить аргументы для вашего параметризованного теста. Вам нужно только указать имя метода. Вот мой метод провайдера аргументов.

    @SneakyThrows
    private static Stream<TestCase> getAddCases() {
        final ObjectMapper mapper = new ObjectMapper();
        TypeReference<List<Case>> typeRef = new TypeReference<>() {};
        final File file = new File("src/test/resources/add-cases.json");
        final List<Case> cases = mapper.readValue(file, typeRef);
        return cases.stream()
                .flatMap(caze -> caze.getCases()
                                        .stream()
                                        .map(el -> new TestCase(caze.getName(), el)));
    }

В приведенном выше коде класс Case используется для сопоставления объекта json с объектом Java, а поле "case" является многомерным массив, для представления каждого теста есть класс с именем TestCase. (В целом, это не важно для вас, так как вы уже можете его проанализировать, но я все равно хотел поместить его здесь).

Наконец, сам метод тестирования.

    @ParameterizedTest(name = "{index} : {arguments}")
    @MethodSource("getAddCases")
    void add_test(TestCase testCase) {
        final List<Integer> values = testCase.getValues();
        int i1 = values.get(0);
        int i2 = values.get(1);
        int e = values.get(2);
        assertEquals(e, MathClass.add(i1, i2));
    }

@ParametrizedTest аннотация принимает аргумент name, в котором вы можете указать шаблон для имен тестов. Я просто поиграл с toString методом класса TestCase, чтобы получить лучшее описание для каждого теста.

@Override
public String toString() {
    return String.format("%s : (%s, %s) ==> %s", name, values.get(0), values.get(1), values.get(2));
}

И вуаля!

Test cases

...