РЕДАКЦИОННОЕ ПРИМЕЧАНИЕ: Мы предоставили множество учебных пособий по JUnit здесь, на Java Code Geeks, таких как Пример начала работы с JUnit , Пример использования утверждений и аннотаций JUnit, Пример аннотаций JUnit и так далее.
Однако для удобства читателей мы предпочли собрать все функции JUnit в одном подробном руководстве. Надеемся, что это вам понравится!
Содержание
1. Внедрение юнит-тестирования
1.1. Что такое юнит-тестирование?
Единица может быть функцией, классом, пакетом или подсистемой. Таким образом, термин «модульное тестирование» относится к практике тестирования таких небольших блоков вашего кода, чтобы гарантировать, что они работают как положено. Например, мы можем проверить, является ли результат тем, что мы ожидали увидеть при некоторых входных данных, или условие является истинным или ложным.
Эта практика помогает разработчикам обнаруживать сбои в своей логике своего кода и улучшать качество своего кода. Кроме того, можно использовать модульное тестирование, чтобы гарантировать, что код будет работать так, как ожидается в случае будущих изменений.
1.2. Тестовое покрытие
В целом, у сообщества разработчиков другое мнение относительно процента кода, который должен быть протестирован (тестовое покрытие). Некоторые разработчики считают, что код должен иметь 100% тестовое покрытие, в то время как другие охватывают тестовое покрытие не более 50%. В любом случае вы должны написать тесты для сложных или критических частей вашего кода.
1.3. Модульное тестирование в Java
Самая популярная среда тестирования в Java — это JUnit . Поскольку это руководство ориентировано на JUnit, более подробная информация об этой среде тестирования будет представлена в следующих разделах. Еще одна популярная среда тестирования в Java — TestNG .
2. JUnit введение
JUnit — это среда тестирования с открытым исходным кодом, которая используется для написания и запуска повторяемых автоматических тестов, поэтому мы можем быть уверены, что наш код работает должным образом. JUnit широко используется в промышленности и может использоваться как отдельная Java-программа (из командной строки) или в среде IDE, такой как Eclipse.
JUnit обеспечивает:
- Утверждения для тестирования ожидаемых результатов.
- Тестовые функции для обмена общими тестовыми данными.
- Наборы тестов для легкой организации и запуска тестов.
- Графические и текстовые тесты бегунов.
JUnit используется для тестирования:
- весь объект
- часть объекта — метод или несколько взаимодействующих методов
- взаимодействие между несколькими объектами
2.1. Простой пример JUnit с использованием Eclipse
В этом разделе мы увидим простой пример JUnit . Сначала мы представим класс, который мы хотели бы протестировать:
Calculate.java
01
02
03
04
05
06
07
08
09
10
|
package com.javacodegeeks.junit; public class Calculate { public int sum( int var1, int var2) { System.out.println( "Adding values: " + var1 + " + " + var2); return var1 + var2; } } |
В приведенном выше исходном коде мы можем заметить, что у класса есть один открытый метод с именем sum()
, который получает в качестве входных данных два целых числа, добавляет их и возвращает результат. Итак, мы проверим этот метод. Для этого мы создадим другой класс, включающий методы, которые будут тестировать каждый из методов предыдущего класса (в этом случае у нас есть только один метод для тестирования). Это самый распространенный способ использования. Конечно, если метод очень сложный и расширенный, мы можем иметь более одного метода тестирования для этого сложного метода. Детали создания тестовых случаев будут представлены в следующих разделах. Ниже приведен код класса CalculateTest.java
, который играет роль нашего тестового класса:
CalculateTest.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
package com.javacodegeeks.junit; import static org.junit.Assert.*; import org.junit.Test; public class CalculateTest { Calculate calculation = new Calculate(); int sum = calculation.sum( 2 , 5 ); int testSum = 7 ; @Test public void testSum() { System.out.println( "@Test sum(): " + sum + " = " + testSum); assertEquals(sum, testSum); } } |
Давайте объясним приведенный выше код. Во-первых, мы видим, что над testSum()
есть аннотация testSum()
. Эта аннотация указывает, что публичный метод void, к которому он прикреплен, может быть запущен в качестве контрольного примера Следовательно, метод testSum()
— это метод, который будет проверять открытый метод sum()
. Мы также можем наблюдать метод assertEquals(sum, testsum)
. Метод assertEquals ([String message], object expected, object actual)
принимает в качестве входных данных два объекта и утверждает, что эти два объекта равны.
Если мы запустим тестовый класс, щелкнув правой кнопкой мыши в тестовом классе и выбрав Run As -> Junit Test , вывод программы будет выглядеть так:
1
2
|
Adding values: 2 + 5 @Test sum (): 7 = 7 |
Чтобы увидеть фактический результат теста JUnit, Eclipse IDE предоставляет окно JUnit, в котором отображаются результаты тестов. В этом случае, когда тест завершается успешно, окно JUnit не показывает никаких ошибок или сбоев, как мы можем видеть на изображении ниже:
Теперь, если мы изменим эту строку кода:
1
|
int testSum = 10 ; |
так что тестируемые целые числа не равны, результат будет:
1
2
|
Adding values: 2 + 5 @Test sum (): 7 = 10 |
А в окне JUnit появится ошибка и будет показано это сообщение:
1
2
|
java.lang.AssertionError: expected: but was: at com.javacodegeeks.junit.CalculateTest.testSum(CalculateTest.java:16) |
2.2. JUnit аннотации
В этом разделе мы упомянем основные аннотации, поддерживаемые в Junit 4. В таблице ниже представлена сводка этих аннотаций:
аннотирование | Описание |
---|---|
@Test |
Аннотация Test указывает, что открытый метод void, к которому он прикреплен, может быть запущен в качестве тестового примера. |
@Before |
Аннотация « Before указывает, что этот метод должен выполняться перед каждым тестом в классе, чтобы выполнить некоторые предварительные условия, необходимые для теста. |
@BeforeClass |
Аннотация BeforeClass указывает, что статический метод, к которому присоединен, должен быть выполнен один раз и перед всеми тестами в классе. Это происходит, когда тестовые методы разделяют вычислительно дорогостоящие настройки (например, подключение к базе данных). |
@After |
Аннотация After указывает, что этот метод выполняется после выполнения каждого теста (например, сброс некоторых переменных после выполнения каждого теста, удаление временных переменных и т. Д.) |
@AfterClass |
Аннотация AfterClass может использоваться, когда необходимо выполнить метод после выполнения всех тестов в классе JUnit Test Case, чтобы очистить дорогостоящую установку (например, отключиться от базы данных). Внимание: метод, прикрепленный к этой аннотации (аналогично BeforeClass ), должен быть определен как статический. |
@Ignore |
Аннотацию Ignore можно использовать, если вы хотите временно отключить выполнение определенного теста. Каждый метод, @Ignore , не будет выполнен. |
Давайте рассмотрим пример тестового класса с некоторыми из упомянутых выше аннотаций.
AnnotationsTest.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
package com.javacodegeeks.junit; import static org.junit.Assert.*; import java.util.*; import org.junit.*; public class AnnotationsTest { private ArrayList testList; @BeforeClass public static void onceExecutedBeforeAll() { System.out.println( "@BeforeClass: onceExecutedBeforeAll" ); } @Before public void executedBeforeEach() { testList = new ArrayList(); System.out.println( "@Before: executedBeforeEach" ); } @AfterClass public static void onceExecutedAfterAll() { System.out.println( "@AfterClass: onceExecutedAfterAll" ); } @After public void executedAfterEach() { testList.clear(); System.out.println( "@After: executedAfterEach" ); } @Test public void EmptyCollection() { assertTrue(testList.isEmpty()); System.out.println( "@Test: EmptyArrayList" ); } @Test public void OneItemCollection() { testList.add( "oneItem" ); assertEquals( 1 , testList.size()); System.out.println( "@Test: OneItemArrayList" ); } @Ignore public void executionIgnored() { System.out.println( "@Ignore: This execution is ignored" ); } } |
Если мы запустим вышеуказанный тест, вывод консоли будет следующим:
1
2
3
4
5
6
7
8
|
@BeforeClass: onceExecutedBeforeAll @Before: executedBeforeEach @Test: EmptyArrayList @After: executedAfterEach @Before: executedBeforeEach @Test: OneItemArrayList @After: executedAfterEach @AfterClass: onceExecutedAfterAll |
2,3. JUnit утверждений
В этом разделе мы представим ряд методов утверждения. Все эти методы предоставляются классом Assert
который расширяет class java.lang.Object
и они полезны для написания тестов с целью обнаружения сбоев. В таблице ниже приведено более подробное объяснение наиболее часто используемых методов утверждения.
Утверждение | Описание |
---|---|
void assertEquals([String message], expected value, actual value) |
Утверждает, что два значения равны. Значения могут быть типа int, short, long, byte, char или java.lang.Object. Первый аргумент — необязательное сообщение String. |
void assertTrue([String message], boolean condition) |
Утверждает, что условие верно. |
void assertFalse([String message],boolean condition) |
Утверждает, что условие ложно. |
void assertNotNull([String message], java.lang.Object object) |
Утверждает, что объект не является нулевым. |
void assertNull([String message], java.lang.Object object) |
Утверждает, что объект является нулевым. |
void assertSame([String message], java.lang.Object expected, java.lang.Object actual) |
Утверждает, что два объекта ссылаются на один и тот же объект. |
void assertNotSame([String message], java.lang.Object unexpected, java.lang.Object actual) |
Утверждает, что два объекта не ссылаются на один и тот же объект. |
void assertArrayEquals([String message], expectedArray, resultArray) |
Утверждает, что ожидаемый массив и полученный массив равны. Тип массива может быть int, long, short, char, byte или java.lang.Object. |
Давайте посмотрим на пример некоторых из вышеупомянутых утверждений.
AssertionsTest.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
package com.javacodegeeks.junit; import static org.junit.Assert.*; import org.junit.Test; public class AssertionsTest { @Test public void test() { String obj1 = "junit" ; String obj2 = "junit" ; String obj3 = "test" ; String obj4 = "test" ; String obj5 = null ; int var1 = 1 ; int var2 = 2 ; int [] arithmetic1 = { 1 , 2 , 3 }; int [] arithmetic2 = { 1 , 2 , 3 }; assertEquals(obj1, obj2); assertSame(obj3, obj4); assertNotSame(obj2, obj4); assertNotNull(obj1); assertNull(obj5); assertTrue(var1 var2); assertArrayEquals(arithmetic1, arithmetic2); } } |
В приведенном выше классе мы видим, как работают эти методы assert.
- Метод
assertEquals()
будет возвращаться нормально, если два сравниваемых объекта равны, в противном случае в окне JUnit будет отображаться сбой, и тест будет прерван. -
assertSame()
иassertNotSame()
проверяют, указывают ли две ссылки на один и тот же объект. -
assertNull()
иassertNotNull()
проверяют, является ли переменная нулевой или нет. -
assertTrue()
иassertFalse()
проверяют, является ли условие или переменная истинным или ложным. -
assertArrayEquals()
будет сравнивать два массива, и если они равны, метод будет работать без ошибок. В противном случае ошибка будет отображаться в окне JUnit, и тест будет прерван.
3. JUnit завершить пример с использованием Eclipse
В этом разделе мы покажем полный пример использования JUnit. Мы подробно рассмотрим, как создавать и запускать тесты, и покажем, как использовать конкретные аннотации и утверждения JUnit.
3.1. Начальные шаги
Давайте создадим Java-проект с именем JUnitGuide . В папке src мы com.javacodegeeks.junit
правой кнопкой мыши и выбираем New -> Package , чтобы создать новый пакет с именем com.javacodegeeks.junit
где мы найдем класс для тестирования. Для тестовых классов рекомендуется создать новую исходную папку, предназначенную для тестов, чтобы тестируемые классы и тестовые классы находились в разных исходных папках. Для этого щелкните правой кнопкой мыши свой проект, выберите « Создать» -> «Исходная папка» , назовите тест новой исходной папки и нажмите « Готово» .
В качестве альтернативы, вы можете создать новую исходную папку, щелкнув правой кнопкой мыши по проекту и выбрав « Свойства» -> «Путь сборки Java» , выберите вкладку « Источник» , выберите « Добавить папку» -> «Создать новую папку» , введите тест имени и нажмите « Готово» .
Вы можете легко увидеть, что в вашем проекте есть две исходные папки:
Вы также можете создать новый пакет во вновь созданной тестовой папке, которая будет называться com.javacodegeeks.junit
, так что ваши тестовые классы не будут расположены в пакете по умолчанию, и мы готовы начать!
3.2. Создайте Java-класс для тестирования
Щелкните правой кнопкой мыши папку src и создайте новый класс Java с именем FirstDayAtSchool.java
. Это будет класс, чьи публичные методы будут проверены.
FirstDayAtSchool.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
package com.javacodegeeks.junit; import java.util.Arrays; public class FirstDayAtSchool { public String[] prepareMyBag() { String[] schoolbag = { "Books" , "Notebooks" , "Pens" }; System.out.println( "My school bag contains: " + Arrays.toString(schoolbag)); return schoolbag; } public String[] addPencils() { String[] schoolbag = { "Books" , "Notebooks" , "Pens" , "Pencils" }; System.out.println( "Now my school bag contains: " + Arrays.toString(schoolbag)); return schoolbag; } } |
3.3. Создать и запустить тестовый пример JUnit
Чтобы создать тестовый пример JUnit для существующего класса FirstDayAtSchool.java
, щелкните его правой кнопкой мыши в представлении Package Explorer и выберите New → JUnit Test Case . Измените исходную папку так, чтобы класс находился в исходной папке для тестирования, и убедитесь, что установлен флажок Новый тест JUnit4 .
Затем нажмите Готово . Если ваш проект не содержит библиотеку JUnit в своем пути к классам, будет показано следующее сообщение, чтобы добавить библиотеку JUnit в путь к классам:
Ниже приведен код класса FirstDayAtSchoolTest.java
, который является нашим тестовым классом:
FirstDayAtSchool.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package com.javacodegeeks.junit; import static org.junit.Assert.*; import org.junit.Test; public class FirstDayAtSchoolTest { FirstDayAtSchool school = new FirstDayAtSchool(); String[] bag1 = { "Books" , "Notebooks" , "Pens" }; String[] bag2 = { "Books" , "Notebooks" , "Pens" , "Pencils" }; @Test public void testPrepareMyBag() { System.out.println( "Inside testPrepareMyBag()" ); assertArrayEquals(bag1, school.prepareMyBag()); } @Test public void testAddPencils() { System.out.println( "Inside testAddPencils()" ); assertArrayEquals(bag2, school.addPencils()); } } |
Теперь мы можем запустить тестовый пример, щелкнув правой кнопкой мыши по классу теста и выбрав Run As -> JUnit Test .
Вывод программы будет выглядеть так:
1
2
3
4
|
Inside testPrepareMyBag() My school bag contains: [Books, Notebooks, Pens] Inside testAddPencils() Now my school bag contains: [Books, Notebooks, Pens, Pencils] |
и в представлении JUnit не будет ни сбоев, ни ошибок. Если мы изменим один из массивов, чтобы он содержал больше ожидаемых элементов:
1
|
String[] bag2 = { "Books" , "Notebooks" , "Pens" , "Pencils" , "Rulers" }; |
и мы снова запускаем тестовый класс, представление JUnit будет содержать ошибку:
Иначе, если мы снова изменим один из массивов, чтобы он содержал элемент, отличный от ожидаемого:
1
|
String[] bag1 = { "Books" , "Notebooks" , "Rulers" }; |
и мы снова запускаем тестовый класс, представление JUnit снова будет содержать ошибку:
3.4. Использование аннотации @Ignore
Давайте посмотрим в приведенном выше примере, как мы можем использовать аннотацию @Ignore
. В тестовом классе FirstDayAtSchoolTest
мы добавим аннотацию testAddPencils()
метод testAddPencils()
. Таким образом, мы ожидаем, что этот метод тестирования будет проигнорирован и не будет выполнен.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
package com.javacodegeeks.junit; import static org.junit.Assert.*; import org.junit.Ignore; import org.junit.Test; public class FirstDayAtSchoolTest { FirstDayAtSchool school = new FirstDayAtSchool(); String[] bag1 = { "Books" , "Notebooks" , "Pens" }; String[] bag2 = { "Books" , "Notebooks" , "Pens" , "Pencils" }; @Test public void testPrepareMyBag() { System.out.println( "Inside testPrepareMyBag()" ); assertArrayEquals(bag1, school.prepareMyBag()); } @Ignore @Test public void testAddPencils() { System.out.println( "Inside testAddPencils()" ); assertArrayEquals(bag2, school.addPencils()); } } |
Действительно, это то, что происходит в зависимости от вывода:
1
2
|
Inside testPrepareMyBag() My school bag contains: [Books, Notebooks, Pens] |
Теперь мы удалим аннотацию @Ignore
из testAddPencils()
и вместо этого будем аннотировать весь класс.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
package com.javacodegeeks.junit; import static org.junit.Assert.*; import org.junit.Ignore; import org.junit.Test; @Ignore public class FirstDayAtSchoolTest { FirstDayAtSchool school = new FirstDayAtSchool(); String[] bag1 = { "Books" , "Notebooks" , "Pens" }; String[] bag2 = { "Books" , "Notebooks" , "Pens" , "Pencils" }; @Test public void testPrepareMyBag() { System.out.println( "Inside testPrepareMyBag()" ); assertArrayEquals(bag1, school.prepareMyBag()); } @Test public void testAddPencils() { System.out.println( "Inside testAddPencils()" ); assertArrayEquals(bag2, school.addPencils()); } } |
Тестовый класс которого не будет выполнен, поэтому результаты не будут отображаться в выводе консоли и в представлении junit:
3.5. Создание комплекта тестов
В этом разделе мы увидим, как создавать наборы тестов. Набор тестов — это набор тестовых наборов из разных классов, которые можно запускать вместе с @Suite
аннотаций @RunWith
и @Suite
. Это очень полезно, если у вас много тестовых классов, и вы хотите запускать их все вместе вместо того, чтобы запускать каждый тест по одному.
Когда класс аннотируется с помощью @RunWith
, JUnit будет вызывать класс, в котором он аннотирован для запуска тестов, вместо того, чтобы использовать бегунок, встроенный в JUnit.
Основываясь на классах предыдущих разделов, мы можем создать два тестовых класса. Один класс протестирует открытый метод prepareMyBag()
а другой — тест метода addPencils()
. Следовательно, в конечном итоге у нас будут следующие классы:
PrepareMyBagTest.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
package com.javacodegeeks.junit; import org.junit.Test; import static org.junit.Assert.*; public class PrepareMyBagTest { FirstDayAtSchool school = new FirstDayAtSchool(); String[] bag = { "Books" , "Notebooks" , "Pens" }; @Test public void testPrepareMyBag() { System.out.println( "Inside testPrepareMyBag()" ); assertArrayEquals(bag, school.prepareMyBag()); } } |
AddPencilsTest.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
package com.javacodegeeks.junit; import org.junit.Test; import static org.junit.Assert.*; public class AddPencilsTest { FirstDayAtSchool school = new FirstDayAtSchool(); String[] bag = { "Books" , "Notebooks" , "Pens" , "Pencils" }; @Test public void testAddPencils() { System.out.println( "Inside testAddPencils()" ); assertArrayEquals(bag, school.addPencils()); } } |
Теперь мы создадим набор тестов, чтобы вместе запустить вышеупомянутые классы. Щелкните правой кнопкой мыши папку исходного кода теста и создайте новый класс Java с именем SuiteTest.java
со следующим кодом:
SuiteTest.java
01
02
03
04
05
06
07
08
09
10
|
package com.javacodegeeks.junit; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith (Suite. class ) @Suite .SuiteClasses({ PrepareMyBagTest. class , AddPencilsTest. class }) public class SuitTest { } |
С @Suite.SuiteClasses
аннотации @Suite.SuiteClasses
вы можете определить, какие тестовые классы будут включены в выполнение.
Таким образом, если вы щелкнете правой кнопкой мыши по комплекту тестов и выберете Run As -> JUnit Test , выполнение обоих классов тестов будет происходить в порядке, определенном в аннотации @Suite.SuiteClasses
.
3,6. Создание параметризованных тестов
В этом разделе мы увидим, как создавать параметризованные тесты. Для этой цели мы будем использовать класс, упомянутый в разделе 2.1, который предоставляет открытый метод для добавления целых чисел. Итак, это будет класс для тестирования.
Но когда тестовый класс можно рассматривать как параметризованный тестовый класс? Конечно, когда он выполняет все следующие требования:
- Класс аннотируется с помощью
@RunWith(Parameterized.class)
.
Как объяснялось в предыдущем разделе, аннотация@RunWith
позволяет JUnit вызывать класс, в котором есть комментарии для запуска тестов, вместо использования встроенного в JUnit@RunWith
запуска.Parameterized
— это бегунок внутри JUnit, который будет запускать один и тот же тестовый набор с другим набором входов. - Класс имеет единственный конструктор, который хранит тестовые данные.
- У класса есть статический метод, который генерирует и возвращает тестовые данные и
@Parameters
аннотацией@Parameters
. - У класса есть тест, который, очевидно, означает, что ему нужен метод с аннотацией
@Test
.
Теперь мы создадим новый тестовый класс с именем CalculateTest.java
, который будет следовать указанным выше рекомендациям. Исходный код этого класса следует.
CalculateTest.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
package com.javacodegeeks.junit; import static org.junit.Assert.assertEquals; import java.util.Arrays; import java.util.Collection; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; @RunWith (Parameterized. class ) public class CalculateTest { private int expected; private int first; private int second; public CalculateTest( int expectedResult, int firstNumber, int secondNumber) { this .expected = expectedResult; this .first = firstNumber; this .second = secondNumber; } @Parameters public static Collection addedNumbers() { return Arrays.asList( new Integer[][] { { 3 , 1 , 2 }, { 5 , 2 , 3 }, { 7 , 3 , 4 }, { 9 , 4 , 5 }, }); } @Test public void sum() { Calculate add = new Calculate(); System.out.println( "Addition with parameters : " + first + " and " + second); assertEquals(expected, add.sum(first, second)); } } |
Как видно из приведенного выше класса, он удовлетворяет всем вышеперечисленным требованиям. Метод addedNumbers
аннотированный @Parameters
возвращает коллекцию массивов. Каждый массив включает номера входов / выходов каждого выполнения теста. Количество элементов в каждом массиве должно совпадать с количеством параметров в конструкторе. Таким образом, в этом конкретном случае каждый массив включает в себя три элемента, два элемента, которые представляют числа, которые будут добавлены, и один элемент для результата.
Если мы запустим тестовый пример CalculateTest
, вывод консоли будет следующим:
1
2
3
4
5
6
7
8
|
Addition with parameters : 1 and 2 Adding values: 1 + 2 Addition with parameters : 2 and 3 Adding values: 2 + 3 Addition with parameters : 3 and 4 Adding values: 3 + 4 Addition with parameters : 4 and 5 Adding values: 4 + 5 |
Как мы видим из выходных данных, тестовый пример выполняется четыре раза, что является количеством входов в методе, @Parameters
аннотацией @Parameters
.
3,7. правила
В этом разделе мы представляем новую особенность JUnit, называемую Правилами, которая позволяет очень гибко добавлять или переопределять поведение каждого метода тестирования в классе тестирования. Для этого следует использовать аннотацию @Rule
чтобы пометить открытые поля тестового класса. Эти поля должны иметь тип MethodRule
, который является изменением того, как тестовый метод запускается и сообщается. Множественные MethodRules
могут быть применены к методу теста. Интерфейс MethodRule
имеет много реализаций, таких как ErrorCollector
который позволяет продолжить выполнение теста после обнаружения первой проблемы, ExpectedException
который позволяет в тесте специфицировать ожидаемые типы исключений и сообщений, TestName
который делает текущее имя теста доступным внутри теста методы и многое другое. За исключением этих уже определенных правил, разработчики могут создавать свои собственные пользовательские правила и использовать их в своих тестовых случаях по своему усмотрению.
Ниже мы представляем, как мы можем использовать одно из существующих правил с именем TestName
в наших собственных тестах. TestName
вызывается, когда тест собирается начать.
NameRuleTest.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package com.javacodegeeks.junit; import static org.junit.Assert.*; import org.junit.*; import org.junit.rules.TestName; public class NameRuleTest { @Rule public TestName name = new TestName(); @Test public void testA() { System.out.println(name.getMethodName()); assertEquals( "testA" , name.getMethodName()); } @Test public void testB() { System.out.println(name.getMethodName()); assertEquals( "testB" , name.getMethodName()); } } |
Мы можем видеть, что аннотация @Rule
отмечает имя открытого поля, которое имеет тип MethodRule
и, в частности, тип TestName
. Затем мы можем использовать в наших тестах это поле name
и найти, например, имя метода теста, в данном конкретном случае.
3,8. категории
Еще одна новая функция JUnit называется Категории и позволяет группировать определенные виды тестов вместе и даже включать или исключать группы (категории). Например, вы можете отделить медленные тесты от быстрых тестов. Чтобы назначить тестовый пример или метод одной из этих категорий, @Category
аннотация @Category
. Ниже приведен пример того, как мы можем использовать эту замечательную функцию JUnit на основе заметок о выпуске JUnit 4.8.
1
2
|
public interface FastTests { /* category marker */ } |
1
2
|
public interface SlowTests { /* category marker */ } |
Во-первых, мы определяем две категории, FastTests и SlowTests. Категория может быть классом или интерфейсом.
01
02
03
04
05
06
07
08
09
10
11
|
public class A { @Test public void a() { fail(); } @Category (SlowTests. class ) @Test public void b() { } } |
В приведенном выше коде мы помечаем тестовый метод b()
класса A
аннотацией @Category
чтобы указать, что этот конкретный метод принадлежит категории SlowTests
. Таким образом, мы можем пометить не только целые классы, но и отдельные методы их тестирования.
1
2
3
4
5
6
|
@Category ({ SlowTests. class , FastTests. class }) public class B { @Test public void c() { } } |
В приведенном выше примере кода мы видим, что весь класс B
@Category
аннотацией @Category
. @Category
тестового класса аннотацией @Category
автоматически включает все его тестовые методы в эту категорию. Мы также видим, что тестовый класс или тестовый метод могут принадлежать к нескольким категориям.
1
2
3
4
5
6
7
|
@RunWith (Categories. class ) @IncludeCategory (SlowTests. class ) @SuiteClasses ({ A. class , B. class }) // Note that Categories is a kind of Suite public class SlowTestSuite { // Will run A.b and B.c, but not A.a } |
В этом примере кода мы заметили, что есть набор тестов с именем SlowTestSuite
. По сути, категории являются своего рода набором. В этом наборе мы наблюдаем новую аннотацию под названием @IncludeCategory
, указывающую, какие категории будут включены в выполнение. В этом конкретном случае будут выполняться методы, относящиеся к категории SlowTests. Следовательно, будет выполнен только тестовый метод b()
класса A
, а также тестовый метод c()
класса B
, оба из которых относятся к категории SlowTests.
1
2
3
4
5
6
7
8
|
@RunWith (Categories. class ) @IncludeCategory (SlowTests. class ) @ExcludeCategory (FastTests. class ) @SuiteClasses ({ A. class , B. class }) // Note that Categories is a kind of Suite public class SlowTestSuite { // Will run A.b, but not A.a or B.c } |
Наконец, мы немного изменим набор тестов и добавим еще одну новую аннотацию под названием @ExcludeCategory
, указывающую, какие категории будут исключены из выполнения. В этом конкретном случае будет выполняться только тестовый метод b()
класса A
, поскольку это единственный тестовый метод, который явно принадлежит категории SlowTests.
Заметим, что в обоих случаях тестовый метод a()
класса A
не будет выполнен, поскольку он не относится ни к одной категории.
4. Запустите тесты JUnit из командной строки
Вы можете запустить свой тест JUnit вне Eclipse, используя класс org.junit.runner.JUnitCore
. Этот класс предоставляет метод runClasses()
который позволяет вам выполнить один или несколько тестовых классов. Возвращаемый тип метода runClasses()
— это объект типа org.junit.runner.Result
. Этот объект можно использовать для сбора информации о тестах. Кроме того, в случае неудачного теста вы можете использовать объект org.junit.runner.notification.Failure
который содержит описание неудачных тестов.
В приведенной ниже процедуре показано, как запустить тест вне Eclipse.
Создайте новый класс Java с именем JunitRunner.java
со следующим кодом:
JunitRunner.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
package com.javacodegeeks.junit; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure; public class JunitRunner { public static void main(String[] args) { Result result = JUnitCore.runClasses(AssertionsTest. class ); for (Failure fail : result.getFailures()) { System.out.println(fail.toString()); } if (result.wasSuccessful()) { System.out.println( "All tests finished successfully..." ); } } } |
Например, мы решили запустить тестовый класс AssertionsTest
.
-
- Откройте командную строку и переместите каталоги вниз, чтобы найти каталог, в котором расположены два класса.
- Скомпилируйте класс Test и класс Runner.
1
|
C:\Users\konstantina\eclipse_luna_workspace\JUnitGuide\ test \com\javacodegeeks\junit>javac -classpath "C:\Users\konstantina\Downloads\junit-4.11.jar" ; "C:\Users\konstantina\Downloads\hamcrest-core-1.3.jar" ; AssertionsTest.java JunitRunner.java |
Как и в Eclipse, мы должны также включить библиотечные jar -файлы JUnit в наш путь к классам.
-
- Теперь запустите
JunitRunner
.
- Теперь запустите
1
|
C:\Users\konstantina\eclipse_luna_workspace\JUnitGuide\ test \com\javacodegeeks\junit>java -classpath "C:\Users\konstantina\Downloads\junit-4.11.jar" ; "C:\Users\konstantina\Downloads\hamcrest-core-1.3.jar" ; JunitRunner |
Вот вывод:
1
|
All tests finished successfully... |
5. Выводы
Это было подробное руководство о среде тестирования JUnit , самой популярной среде тестирования в Java.
Если вам понравилось, подпишитесь на нашу новостную рассылку, чтобы получать еженедельные обновления и бесплатные обзоры! Кроме того, проверьте JCG Academy для более углубленного обучения!