简体   繁体   English

为验证字符串输入编写参数化测试的最佳实践是什么?

[英]What is the best practice to write parameterized tests for validating string inputs?

I'm writing a parameterized unit test for a code something similar to below, to make sure that my tests cover all the possible input cases and the system behaves as expected. 我正在为类似于下面的代码编写参数化单元测试,以确保我的测试涵盖所有可能的输入案例,并且系统按预期运行。

I came up with 3 approaches ie testGetAnimalMood1, testGetAnimalMood2, testGetAnimalMood3: 我提出了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 looks cleaner than testGetAnimalMood1 by using MethodSource. testGetAnimalMood2通过使用MethodSource看起来比testGetAnimalMood1更干净。 However at the same time it's harder to read which values are used to test than before. 然而,与此同时,更难以阅读用于测试的值。 Thinking that there is not much value added by getAnimalMoodParameters2 method, which version is a better practice to use? 认为getAnimalMoodParameters2方法没有多少附加值,哪个版本更好用?

testGetAnimalMood3 looks even cleaner but it has the potential danger of validating my false logic as it's using a similar approach with the test under code to get the values. testGetAnimalMood3看起来更清晰,但它有可能验证我的错误逻辑,因为它使用类似的方法在代码下进行测试以获取值。 Also I might not be able catch possible typos if I do not write the values as strings. 如果我不将值写为字符串,我也可能无法捕获可能的拼写错误。 But a counter argument would be, another user trying to modify this code might not be able to understand the behavior by just looking at those arbitrary strings. 但是一个反驳的论点是,另一个试图修改这段代码的用户可能无法通过查看那些任意字符串来理解行为。

Thinking all those arguments or if you have to add more, which one is the best approach? 思考所有这些论点或者如果你必须添加更多,哪一个是最好的方法?

I use this setup when I'm writing parameterized tests: 我在编写参数化测试时使用此设置:

@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) tells JUnit to run your class with different parameters. @RunWith(Parameterized.class)告诉JUnit使用不同的参数运行你的类。

The static method annotated with @Parameters is your method source. 使用@Parameters注释的静态方法是您的方法源。

The two fields annotated with @Parameter tell JUnit which parameter at which index should be picked. @Parameter注释的两个字段告诉JUnit应该选择哪个索引的参数。

And the rest should be self explaining 其余的应该是自我解释

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM