阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

参数化测试

23次阅读
没有评论

共计 2028 个字符,预计需要花费 6 分钟才能阅读完成。

如果待测试的输入和输出是一组数据,可以把测试数据组织起来,用不同的测试数据调用相同的测试方法,这就是参数化测试。

参数化测试和普通测试稍微不同的地方在于,一个测试方法需要接收至少一个参数,然后,传入一组参数反复运行。

JUnit 提供了一个 @ParameterizedTest 注解,用来进行参数化测试。

假设我们想对 Math.abs() 进行测试,先用一组正数进行测试:

@ParameterizedTest
@ValueSource(ints = { 0, 1, 5, 100})
void testAbs(int x) {assertEquals(x, Math.abs(x));
}

再用一组负数进行测试:

@ParameterizedTest
@ValueSource(ints = { -1, -5, -100})
void testAbsNegative(int x) {assertEquals(-x, Math.abs(x));
}

注意到参数化测试的注解是@ParameterizedTest,而不是普通的@Test

实际的测试场景往往没有这么简单。假设我们自己编写了一个 StringUtils.capitalize() 方法,它会把字符串的第一个字母变为大写,后续字母变为小写:

public class StringUtils {public static String capitalize(String s) {if (s.length() == 0) {return s;
        }
        return Character.toUpperCase(s.charAt(0)) + s.substring(1).toLowerCase();}
}

要用参数化测试的方法来测试,我们不但要给出输入,还要给出预期输出。因此,测试方法至少需要接收两个参数:

@ParameterizedTest
void testCapitalize(String input, String result) {assertEquals(result, StringUtils.capitalize(input));
}

现在问题来了:参数如何传入?

最简单的方法是通过 @MethodSource 注解,它允许我们编写一个同名的静态方法来提供测试参数:

@ParameterizedTest
@MethodSource
void testCapitalize(String input, String result) {assertEquals(result, StringUtils.capitalize(input));
}

static List<Arguments> testCapitalize() {return List.of(// arguments:
            Arguments.of("abc", "Abc"), //
            Arguments.of("APPLE", "Apple"), //
            Arguments.of("gooD", "Good"));
}

上面的代码很容易理解:静态方法 testCapitalize() 返回了一组测试参数,每个参数都包含两个String,正好作为测试方法的两个参数传入。

提示

如果静态方法和测试方法的名称不同,@MethodSource 也允许指定方法名。但使用默认同名方法最方便。

另一种传入测试参数的方法是使用 @CsvSource,它的每一个字符串表示一行,一行包含的若干参数用, 分隔,因此,上述测试又可以改写如下:

@ParameterizedTest
@CsvSource({"abc, Abc", "APPLE, Apple", "gooD, Good"})
void testCapitalize(String input, String result) {assertEquals(result, StringUtils.capitalize(input));
}

如果有成百上千的测试输入,那么,直接写 @CsvSource 就很不方便。这个时候,我们可以把测试数据提到一个独立的 CSV 文件中,然后标注上@CsvFileSource

@ParameterizedTest
@CsvFileSource(resources = { "/test-capitalize.csv"})
void testCapitalizeUsingCsvFile(String input, String result) {assertEquals(result, StringUtils.capitalize(input));
}

JUnit 只在 classpath 中查找指定的 CSV 文件,因此,test-capitalize.csv这个文件要放到 test 目录下,内容如下:

apple, Apple
HELLO, Hello
JUnit, Junit
reSource, Resource

练习

StringUtils 进行参数化测试。

下载练习

小结

使用参数化测试,可以提供一组测试数据,对一个测试方法反复测试;

参数既可以在测试代码中写死,也可以通过 @CsvFileSource 放到外部的 CSV 文件中。

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-08-05发表,共计2028字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中