Какова лучшая практика для написания параметризованных тестов для проверки ввода строки? - PullRequest
0 голосов
/ 03 апреля 2019

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

Я предложил 3 подхода: testGetAnimalMood1, testGetAnimalMood2, testGetAnimalMood3:

public class Exp {

    enum Animal{
        CAT("Cat is happy"),
        DOG("Dog is sad");

        Animal(String mood){
            this.mood = mood;
        }

        private String mood;

        public String getMood(){
            return this.mood;
        }
    }

    public static String getAnimalsMood(String animal){
        return Animal.valueOf(animal).getMood();
    }
}

public class ExpTest {

    @ParameterizedTest
    @CsvSource({"CAT, Cat is happy", "DOG, Dog is sad"})
    public void testGetAnimalMood1(String animal, String expected){
        String mood = Exp.getAnimalsMood(animal);

        Assertions.assertEquals(expected, mood);
    }

    @ParameterizedTest
    @MethodSource("getAnimalMoodParameters2")
    public void testGetAnimalMood2(String animal, String expected){
        String mood = Exp.getAnimalsMood(animal);

        Assertions.assertEquals(expected, mood);
    }

    public static Stream<Arguments> getAnimalMoodParameters2(){
        return Stream.of(Arguments.of("CAT", "Cat is happy"),Arguments.of("DOG", "Dog is sad"));
    }

    @ParameterizedTest
    @MethodSource("getAnimalMoodParameters3")
    public void testGetAnimalMood3(String animal, String expected){
        String mood = Exp.getAnimalsMood(animal);

        Assertions.assertEquals(expected, mood);
    }

    public static Stream<Arguments> getAnimalMoodParameters3(){
        return Arrays.stream(Exp.Animal.values()).map(e -> Arguments.of(e.name(), e.getMood()));
    }

}

testGetAnimalMood2 выглядит чище, чем testGetAnimalMood1, с помощью MethodSource.Однако в то же время сложнее понять, какие значения используются для проверки, чем раньше.Думая, что метод getAnimalMoodParameters2 не имеет большой ценности, какую версию лучше использовать?

testGetAnimalMood3 выглядит еще чище, но есть потенциальная опасность проверки моей ложной логики, поскольку он использует аналогичный подход стест по коду, чтобы получить значения.Кроме того, я не смог бы поймать возможные опечатки, если я не пишу значения в виде строк.Но встречным аргументом будет то, что другой пользователь, пытающийся изменить этот код, может не понять поведение, просто взглянув на эти произвольные строки.

Думая обо всех этих аргументах или если вам нужно добавить еще, какой из них лучший?

1 Ответ

0 голосов
/ 03 апреля 2019

Я использую эту настройку, когда пишу параметризованные тесты:

@RunWith(Parameterized.class)
public class MyTest {
    @Parameter(0)
    public String animal;
    @Parameter(1)
    public String expected;

    @Parameters
    public static List<String[]> parameters() {
        return Arrays.asList(
            new String[]{"CAT", "Cat is happy"},
            new String[]{"DOG", "Dog is sad"}
        );
    }

    @Test
    public void testGetAnimalMood(){
        String mood = Exp.getAnimalsMood(animal);

        Assertions.assertEquals(expected, mood);
    }
}

@RunWith(Parameterized.class) говорит JUnit запустить ваш класс с другими параметрами.

Статический метод, помеченный @Parameters, является источником вашего метода.

Два поля, помеченные @Parameter, сообщают JUnit, какой параметр по какому индексу должен быть выбран.

А остальное должно быть самоочевидным

...