使用JUnit 5进行更清洁的参数化测试
參數(shù)化單元測(cè)試的總體思路是對(duì)不同的數(shù)據(jù)運(yùn)行相同的測(cè)試方法。 在JUnit 4中創(chuàng)建參數(shù)化測(cè)試遠(yuǎn)非完美。 現(xiàn)有體系結(jié)構(gòu)存在許多問(wèn)題:將參數(shù)定義為類(lèi)字段,并且需要使用構(gòu)造函數(shù)來(lái)創(chuàng)建它們,不能將參數(shù)化和非參數(shù)化測(cè)試混合在一個(gè)測(cè)試類(lèi)中,并且內(nèi)置數(shù)據(jù)源非常有限。 幸運(yùn)的是,所有這些都在JUnit 5中得到了改進(jìn)!
注意:作為JUnit 4參數(shù)化測(cè)試的替代方法,您可以使用JUnitParams庫(kù)來(lái)解決我提到的許多問(wèn)題(請(qǐng)?jiān)诖颂幉榭从嘘P(guān)JUnitParams的博客文章: http : //blog.codeleak.pl/2013/12/parametrized-junit- tests-with.html )。
如何開(kāi)始?
要開(kāi)始在Junit 5中進(jìn)行參數(shù)化測(cè)試,您需要向項(xiàng)目添加必需的依賴(lài)項(xiàng):向項(xiàng)目添加org.junit.jupiter:junit-jupiter-params:${junitJupiterVersion}依賴(lài)項(xiàng)以使用參數(shù)化測(cè)試,參數(shù)提供程序和轉(zhuǎn)換器。
SUT –被測(cè)系統(tǒng)
我創(chuàng)建的所有示例都在測(cè)試FizzBu??zz類(lèi):
public class FizzBuzz {private static final int THREE = 3;private static final int FIVE = 5;public String calculate(int number) {if (isDivisibleBy(number, THREE) && isDivisibleBy(number, FIVE)) {return "FizzBuzz";}if (isDivisibleBy(number, THREE)) {return "Fizz";}if (isDivisibleBy(number, FIVE)) {return "Buzz";}return String.valueOf(number);}private static boolean isDivisibleBy(int dividend, int divisor) {return dividend % divisor == 0;} }盡管FizzBu??zz非常簡(jiǎn)單,但是它也可以用于演示更高級(jí)的單元測(cè)試技術(shù),例如實(shí)現(xiàn)參數(shù)化測(cè)試。
我在JUnit 5中的第一個(gè)參數(shù)化測(cè)試
要在JUnit 5中創(chuàng)建參數(shù)化測(cè)試,請(qǐng)使用@org.junit.jupiter.params.ParameterizedTest (而不是@Test )注釋測(cè)試方法,并提供參數(shù)來(lái)源:
@ParameterizedTest(name = "{index} => calculate({0})") @ValueSource(ints = {1, 2, 4, 7, 11, 13, 14}) public void returnsNumberForNumberNotDivisibleByThreeAndFive(int number, TestInfo testInfo) {assertThat(fizzBuzz.calculate(number)).isEqualTo("" + number); }注釋具有可選的name屬性,用于自定義調(diào)用顯示名稱(chēng)。 可用的模板變量:{index}->當(dāng)前調(diào)用索引(從1開(kāi)始),{arguments}->完整的,逗號(hào)分隔的參數(shù)列表,{0},{1},…->一個(gè)單獨(dú)的參數(shù)。
在此示例中, @org.junit.jupiter.params.provider.ValueSource提供對(duì)整數(shù)文字值數(shù)組的訪問(wèn)。 必須在此批注中提供一種輸入類(lèi)型(字符串,實(shí)例,長(zhǎng)整型或雙精度型)。
我還提供了由org.junit.jupiter.api.extension.ParameterResolver解析的其他參數(shù)。 請(qǐng)注意,由參數(shù)源解析的方法參數(shù)需要在參數(shù)列表中排在首位。
更多論點(diǎn)來(lái)源
@MethodSource
@ParameterizedTest(name = "{index} => calculate({0})") @MethodSource(names = {"divisibleByThree", "divisibleByThreeButNotFive"}) void returnFizzForNumberDivisibleByThree(int number) {assertThat(fizzBuzz.calculate(number)).isEqualTo("Fizz"); }@org.junit.jupiter.params.provider.MethodSource引用返回自變量源的方法(1個(gè)或更多)。 在此示例中,有兩種方法:
private static Stream<Integer> divisibleByThree() {int[] ints = new int[]{18, 21};return Stream.of(3, 6, 9, 12); }// The returned array will be converted to a Stream private static String[] divisibleByThreeButNotFive() {return new String[]{"18", "21"}; }提供參數(shù)的方法必須是靜態(tài)的,不能包含任何參數(shù),并且必須返回Stream,Iterable,Iterator或數(shù)組。 您可能會(huì)注意到, divisibleByThreeButNotFive()方法返回一個(gè)字符串?dāng)?shù)組。 由于內(nèi)置了隱式參數(shù)轉(zhuǎn)換器,因此可以很好地工作。 當(dāng)參數(shù)源是CSV時(shí)(這在下面有更多說(shuō)明),這確實(shí)很有用。 此外,可以使用自定義參數(shù)轉(zhuǎn)換器來(lái)轉(zhuǎn)換參數(shù)。
要解析多個(gè)參數(shù),方法源將返回org.junit.jupiter.params.provider.Arguments實(shí)例流( org.junit.jupiter.params.provider.ObjectArrayArguments ):
@ParameterizedTest(name = "{index} => calculate({0}) should return {1}") @MethodSource(names = {"fizzBuzz"}) void fizzBuzz(int number, String expectedResult) {assertThat(fizzBuzz.calculate(number)).isEqualTo(expectedResult); }private static Stream<Arguments> fizzBuzz() {return Stream.of(ObjectArrayArguments.create(1, "1"),ObjectArrayArguments.create(2, "2"),ObjectArrayArguments.create(3, "Fizz"),ObjectArrayArguments.create(4, "4"),ObjectArrayArguments.create(5, "Buzz"),ObjectArrayArguments.create(6, "Fizz"),ObjectArrayArguments.create(7, "7"),ObjectArrayArguments.create(8, "8"),ObjectArrayArguments.create(9, "Fizz"),ObjectArrayArguments.create(15, "FizzBuzz")); }@CsvFileSource
提供參數(shù)源的另一種非常有趣的方法是org.junit.jupiter.params.provider.CsvFileSource ,它從類(lèi)路徑中的多個(gè)CSV文件之一中提供參數(shù):
@ParameterizedTest(name = "{index} => calculate({0}) should return {1}") @CsvFileSource(resources = {"/fizzbuzz/fizzbuzz_1.csv", "/fizzbuzz/fizzbuzz_2.csv"}, delimiter = ';') void fizzBuzzCsv(int number, String expectedResult) {assertThat(fizzBuzz.calculate(number)).isEqualTo(expectedResult); }其他論點(diǎn)
- @EnumSource提供了使用Enum常量的便捷方法。
- @CsvSource允許您將參數(shù)列表表示為以逗號(hào)分隔的值
- @ArgumentsSource可用于指定自定義,可重用的參數(shù)提供程序。
享受JUnit 5中的參數(shù)化測(cè)試!
資源資源
可以在GitHub上找到本文中介紹的所有示例: https : //github.com/kolorobot/unit-testing-demo
查看官方的JUnit 5文檔以了解更多信息: http : //junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests
翻譯自: https://www.javacodegeeks.com/2017/06/cleaner-parameterized-tests-junit-5.html
總結(jié)
以上是生活随笔為你收集整理的使用JUnit 5进行更清洁的参数化测试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何调低电脑内存时序(如何调低电脑内存时
- 下一篇: 大数据摄取:Flume,Kafka和Ni