Статьи

Учебник JUnit по модульному тестированию — Руководство ULTIMATE (PDF Download)

РЕДАКЦИОННОЕ ПРИМЕЧАНИЕ: Мы предоставили множество учебных пособий по 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

Рисунок 1: Окно 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
public void method()
Аннотация Test указывает, что открытый метод void, к которому он прикреплен, может быть запущен в качестве тестового примера.
@Before
public void method()
Аннотация « Before указывает, что этот метод должен выполняться перед каждым тестом в классе, чтобы выполнить некоторые предварительные условия, необходимые для теста.
@BeforeClass
public static void method()
Аннотация BeforeClass указывает, что статический метод, к которому присоединен, должен быть выполнен один раз и перед всеми тестами в классе. Это происходит, когда тестовые методы разделяют вычислительно дорогостоящие настройки (например, подключение к базе данных).
@After
public void method()
Аннотация After указывает, что этот метод выполняется после выполнения каждого теста (например, сброс некоторых переменных после выполнения каждого теста, удаление временных переменных и т. Д.)
@AfterClass
public static void method()
Аннотация AfterClass может использоваться, когда необходимо выполнить метод после выполнения всех тестов в классе JUnit Test Case, чтобы очистить дорогостоящую установку (например, отключиться от базы данных). Внимание: метод, прикрепленный к этой аннотации (аналогично BeforeClass ), должен быть определен как статический.
@Ignore
public static void method()
Аннотацию 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 где мы найдем класс для тестирования. Для тестовых классов рекомендуется создать новую исходную папку, предназначенную для тестов, чтобы тестируемые классы и тестовые классы находились в разных исходных папках. Для этого щелкните правой кнопкой мыши свой проект, выберите « Создать» -> «Исходная папка» , назовите тест новой исходной папки и нажмите « Готово» .

Создайте новую исходную папку с именем test.

Рисунок 2: Создайте новую исходную папку с именем test .

Наконечник
В качестве альтернативы, вы можете создать новую исходную папку, щелкнув правой кнопкой мыши по проекту и выбрав « Свойства» -> «Путь сборки Java» , выберите вкладку « Источник» , выберите « Добавить папку» -> «Создать новую папку» , введите тест имени и нажмите « Готово» .

Вы можете легко увидеть, что в вашем проекте есть две исходные папки:

фигура 2

Рисунок 3

Вы также можете создать новый пакет во вновь созданной тестовой папке, которая будет называться 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 .

Создайте новый тестовый класс.

Рисунок 4: Создайте новый тестовый класс.

Затем нажмите Готово . Если ваш проект не содержит библиотеку JUnit в своем пути к классам, будет показано следующее сообщение, чтобы добавить библиотеку JUnit в путь к классам:

Добавьте библиотеку JUnit4 в путь сборки вашего проекта.

Рисунок 5: Добавьте библиотеку JUnit4 в путь сборки вашего проекта.

Ниже приведен код класса 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 будет содержать ошибку:

Провал теста

Рисунок 6: Провал теста

Иначе, если мы снова изменим один из массивов, чтобы он содержал элемент, отличный от ожидаемого:

1
String[] bag1 = { "Books", "Notebooks", "Rulers" };

и мы снова запускаем тестовый класс, представление JUnit снова будет содержать ошибку:

Провал теста

Рисунок 7: Провал теста

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:

Игнорировать аннотацию

Рисунок 8

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 для более углубленного обучения!

Скачать
Вы можете скачать полный исходный код этого руководства здесь: JUnitGuide.zip