Въведение в JUnitParams

1. Общ преглед

В тази статия ще разгледаме библиотеката JUnitParams и нейното използване. Просто казано, тази библиотека осигурява лесна параметризация на тестовите методи в JUnit тестове.

Има ситуации, при които единственото нещо, което се променя между множество тестове, са параметрите. Самият JUnit има поддръжка на параметризиране и JUnitParams значително подобрява тази функционалност.

2. Зависимост на Maven

За да използваме JUnitParams в нашия проект, трябва да го добавим към нашия pom.xml :

 pl.pragmatists JUnitParams 1.1.0 

Най-новата версия на библиотеката можете да намерите тук.

3. Тестов сценарий

Нека създадем клас, който прави безопасното добавяне на две цели числа. Това трябва да върне Integer.MAX_VALUE, ако прелива, и Integer.MIN_VALUE, ако се прелива :

public class SafeAdditionUtil { public int safeAdd(int a, int b) { long result = ((long) a) + b; if (result > Integer.MAX_VALUE) { return Integer.MAX_VALUE; } else if (result < Integer.MIN_VALUE) { return Integer.MIN_VALUE; } return (int) result; } }

4. Изграждане на прост метод за изпитване

Ще трябва да тестваме изпълнението на метода за различни комбинации от входни стойности, за да сме сигурни, че изпълнението е вярно за всички възможни сценарии. JUnitParams предоставя повече от един начин за постигане на параметризираното създаване на тест.

Нека вземем основния подход с минимално количество кодиране и да видим как се прави. След това можем да видим какви са другите възможни начини за внедряване на тестовите сценарии с помощта на JUnitParams :

@RunWith(JUnitParamsRunner.class) public class SafeAdditionUtilTest { private SafeAdditionUtil serviceUnderTest = new SafeAdditionUtil(); @Test @Parameters({ "1, 2, 3", "-10, 30, 20", "15, -5, 10", "-5, -10, -15" }) public void whenWithAnnotationProvidedParams_thenSafeAdd( int a, int b, int expectedValue) { assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); } }

Сега нека видим как този тестов клас се различава от обикновения JUnit тестов клас.

Първото нещо, което забелязваме, е, че в анотацията на класа има различен тестов бегач - JUnitParamsRunner .

Преминавайки към тестовия метод, виждаме, че тестовият метод е анотиран с @Parameters анотация с масив от входни параметри. Той посочва различни тестови сценарии, които ще бъдат използвани за тестване на нашия метод за обслужване.

Ако стартираме теста с помощта на Maven, ще видим, че изпълняваме четири тестови случая и нито един . Резултатът ще бъде подобен на следния:

------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.baeldung.junitparams.SafeAdditionUtilTest Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.068 sec - in com.baeldung.junitparams.SafeAdditionUtilTest Results : Tests run: 4, Failures: 0, Errors: 0, Skipped: 0

5. Различни видове параметризиране на методите за изпитване

Предоставянето на тестови параметри директно в анотацията със сигурност не е най-четливият начин, ако имаме много възможни сценарии, които трябва да бъдат тествани. JUnitParams предлага набор от различни подходи, които можем да използваме за създаване на параметризирани тестове:

  • Директно в анотацията @Parameters (използвана в примера по-горе)
  • Използване на именен метод за тестване, дефиниран в анотацията
  • Използване на метод, картографиран от името на метода на теста
  • Именен тестов клас, дефиниран в анотацията
  • Използване на CSV файл

Нека изследваме подходите един по един.

5.1. Директно в @Parameters Annotation

Вече използвахме този подход в примера, който опитахме. Това, което трябва да имаме предвид, е, че трябва да предоставяме масив от низове на параметри. В рамките на низ от параметри всеки параметър е разделен със запетая.

Например масивът ще бъде под формата на {“1, 2, 3”, “-10, 30, 20”} и един набор от параметри е представен като “1, 2, 3” .

Ограничението на този подход е, че можем да предоставим само примитиви и String s като тестови параметри. Не е възможно да се подават и обекти като параметри на метода на теста.

5.2. Метод на параметрите

Можем да предоставим параметри на метода за тестване, използвайки друг метод в класа. Нека първо видим пример:

@Test @Parameters(method = "parametersToTestAdd") public void whenWithNamedMethod_thenSafeAdd( int a, int b, int expectedValue) { assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); } private Object[] parametersToTestAdd() { return new Object[] { new Object[] { 1, 2, 3 }, new Object[] { -10, 30, 20 }, new Object[] { Integer.MAX_VALUE, 2, Integer.MAX_VALUE }, new Object[] { Integer.MIN_VALUE, -8, Integer.MIN_VALUE } }; }

Тестовият метод е анотиран по отношение на метода parametersToAdd () и той извлича параметрите чрез стартиране на посочения метод.

Спецификацията на метода на доставчика трябва да върне масив от обекти като резултат. Ако метод с даденото име не е наличен, тестовият случай се проваля с грешката:

java.lang.RuntimeException: Could not find method: bogusMethodName so no params were used.

5.3. Метод, картографиран от името на метода на теста

Ако не посочим нищо в анотацията @Parameters , JUnitParams се опитва да зареди метод на доставчик на тестови данни въз основа на името на метода на теста. Името на метода е конструирано като “parametersFor” +:

@Test @Parameters public void whenWithnoParam_thenLoadByNameSafeAdd( int a, int b, int expectedValue) { assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); } private Object[] parametersForWhenWithnoParam_thenLoadByNameSafe() { return new Object[] { new Object[] { 1, 2, 3 }, new Object[] { -10, 30, 20 }, new Object[] { Integer.MAX_VALUE, 2, Integer.MAX_VALUE }, new Object[] { Integer.MIN_VALUE, -8, Integer.MIN_VALUE } }; }

В горния пример името на метода за тестване е когатоWithnoParam_shouldLoadByNameAbdSafeAdd () .

Следователно, когато се изпълнява тестовият метод, той търси метод на доставчик на данни с име параметриForWhenWithnoParam_shouldLoadByNameAbdSafeAdd () .

Тъй като този метод съществува, той ще зареди данни от него и ще стартира теста. Ако няма такъв метод, който да съответства на необходимото име, тестът е неуспешен, както в горния пример.

5.4. Именен тестов клас, дефиниран в анотацията

Подобно на начина, по който се позовахме на метод за доставчик на данни в предишен пример, можем да се обърнем към отделен клас, за да предоставим данните за нашия тест:

@Test @Parameters(source = TestDataProvider.class) public void whenWithNamedClass_thenSafeAdd( int a, int b, int expectedValue) { assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); } public class TestDataProvider { public static Object[] provideBasicData() { return new Object[] { new Object[] { 1, 2, 3 }, new Object[] { -10, 30, 20 }, new Object[] { 15, -5, 10 }, new Object[] { -5, -10, -15 } }; } public static Object[] provideEdgeCaseData() { return new Object[] { new Object[] { Integer.MAX_VALUE, 2, Integer.MAX_VALUE }, new Object[] { Integer.MIN_VALUE, -2, Integer.MIN_VALUE }, }; } }

Можем да имаме произволен брой доставчици на тестови данни в клас, като се има предвид, че името на метода започва с „предоставяне“. Ако е така, изпълнителят избира тези методи и връща данните.

Ако нито един метод на клас не отговаря на това изискване, въпреки че тези методи връщат масив от обекти , тези методи ще бъдат игнорирани.

5.5. Използване на CSV файл

Можем да използваме външен CSV файл за зареждане на тестовите данни. Това помага, ако броят на възможните тестови случаи е доста значителен или ако тестовите случаи често се сменят. Промените могат да се извършват, без да се засягат тестовите кодове.

Да кажем, че имаме CSV файл с тестови параметри като JunitParamsTestParameters.csv :

1,2,3 -10, 30, 20 15, -5, 10 -5, -10, -15

Сега нека разгледаме как този файл може да се използва за зареждане на тестови параметри в тестовия метод:

@Test @FileParameters("src/test/resources/JunitParamsTestParameters.csv") public void whenWithCsvFile_thenSafeAdd( int a, int b, int expectedValue) { assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); }

Едно ограничение на този подход е, че не е възможно да се предават сложни обекти. Само примитиви и String са валидни.

6. Заключение

В този урок разгледахме как можем накратко да използваме функционалностите на JUnitParams .

Също така разгледахме различни подходи, които библиотеката ни предоставя, за да предоставим тестови параметри на нашите тестови методи - далеч над това, което JUnit може да направи сам.

Както винаги, изходният код може да бъде намерен в GitHub.