JavaRush/Курсы/JSP & Servlets/Первые тесты с помощью JUnit

Первые тесты с помощью JUnit

Открыта

Подключаем фреймворк JUnit

Для тестирования Java-кода у нас есть шикарный фреймворк под названием JUnit. Он отлично работает, постоянно обновляется, очень популярен и, конечно, с ним очень плотно интегрирована Intellij IDEA.

Сейчас все пользуются пятой версией этого фреймворка — JUnit 5, хотя во многих проектах ты еще можешь встретить его четвертую версию. Они не сильно отличаются, но мы все равно рассмотрим самую последнюю. Думаю, к тому времени, когда ты начнешь активно писать тесты, ты одобришь мой выбор.

Итак, как добавить в проект JUnit? После изучения Maven это будет просто: просто добавь этот код в свой pom.xml:

<dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.8.1</version> <scope>test</scope> </dependency>

Кстати, если ты хочешь, чтобы Maven на этапе сборки (test stage) запустил твои тесты, то в pom.xml нужно добавить еще один фрагмент:

<plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.19.1</version> <dependencies> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-surefire-provider</artifactId> <version>1.3.2</version> </dependency> </dependencies> </plugin>

Аннотация @Test

Допустим, у тебя есть класс, который ты хочешь протестировать. Как это лучше всего сделать? Давай начнем с какого-нибудь примера, а то сложно тестировать абстрактный класс :)

Предположим, у нас есть класс Calculator, которые умеет выполнять 4 базовые операции: сложение, вычитание, умножение и деление. Напишем его:

class Calculator {
    	public int add(int a, int b) {
        	return a+b;
    	}

    	public int sub(int a, int b) {
        	return a-b;
    	}

    	public int mul (int a, int b) {
        	return a*b;
    	}

    	public int div(int a, int b) {
        	return a/b;
    	}
}

Мы хотим протестировать методы этого класса. Мало ли, в будущем наменяют чего-нибудь и все перестанет работать. Как нам написать для него тесты?

Нам нужно создать еще один класс. Для этого обычно берут то же имя и добавляют суффикс Test. Для каждого метода нужно добавить хотя бы один тестовый метод. Пример:

class CalculatorTest {
   	@Test
    	public void add() {
    	}
   	@Test
    	public void sub() {
        }
   	@Test
    	public void mul() {
    	}
   	@Test
    	public void div() {
    	}
}

Раньше существовало требование, чтобы имя метода начиналось со слова test, но теперь это не нужно.

Примеры тестов JUnit

Давай напишем несколько примеров, в которых протестируем методы нашего класса CalculatorTest :

class CalculatorTest {
   	@Test
    	public void add() {
        	Calculator calc = new Calculator();
        	int result = calc.add(2, 3);
        	assertEquals(5, result);
    	}

   	@Test
    	public void sub() {
        	Calculator calc = new Calculator();
        	int result = calc.sub(10, 10);
        	assertEquals(0, result);
        }

   	@Test
    	public void mul() {
        	Calculator calc = new Calculator();
        	int result = calc.mul(-5, -3);
        	assertEquals(15, result);
    	}

   	@Test
    	public void div() {
        	Calculator calc = new Calculator();
        	int result = calc.div(2, 3);
        	assertEquals(0, result);
    	}
}

Вот так выглядит типичный тест с использованием JUnit. Из интересного: тут используется специальный метод assertEquals(): он сравнивает переданные ему параметры, о чем говорит слово equals в его названии.

Если параметры, переданные в assertEquals(), неравны, то метод кинет исключение и тест будет считаться проваленным. Это исключение не помешает выполнению остальных тестов.

Комментарии (24)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Алексей
Уровень 34
16 декабря 2024, 12:29
Может я че пропустил но где рассказывали что в plugins можно dependecies засовывать и в чем смысл?
Олег
Уровень 106
Expert
1 августа 2024, 17:41
dependency Выделило красным в pom. Что делать?
Рубен
Уровень 80
20 сентября 2024, 19:00
проверять синтаксис
TaurnilTechnical Lead в ООО "Теком"Expert
31 января 2024, 19:00
<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
	<version>2.19.1</version>
	<dependencies>
    	<dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-surefire-provider</artifactId>
            <version>1.3.2</version>
    	</dependency>
	</dependencies>
</plugin>
здесь пропущена секция
<groupId>org.apache.maven.plugins</groupId>
Anonymous #3322801
Уровень 1
Expert
15 июля 2023, 19:30
А вот мне интересно.... только у меня работает сборка проекта только через terminal или у всех так? intellij idea фейлит все сборки с плагином maven-surefire-plugin Ошибка:
The forked VM terminated without properly saying goodbye. VM crash or System.exit called?
Command was cmd.exe /X /C ""C:\Program Files\Java\jdk-18.0.2.1\bin\java" -jar C:\Users\User\IdeaProjects\MVNproject\target\surefire\surefirebooter855731060151577919.jar C:\Users\User\IdeaProjects\MVNproject\target\surefire\surefire13033870546199411150tmp C:\Users\User\IdeaProjects\MVNproject\target\surefire\surefire_011788137880531467678tmp"
работает только в таком режиме:
<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19.1</version>
    <configuration>
        <skipTests>true</skipTests>
    </configuration>
</plugin>
но в таком случае весь смысл этого плагина пропадает....
Anonymous #3322801
Уровень 1
Expert
16 июля 2023, 14:12
разобралась, если у вас выскакивает ошибка:
'java.lang.Object org.apache.maven.surefire.util.internal.StringUtils.requireNonNull(java.lang.Object)'
то просто смените версию на 2.22.2
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
если даже будет гореть красным, то ниче страшного и так будет работать
Anonymous #3322801
Уровень 1
Expert
16 июля 2023, 14:33
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>untitled</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>18</maven.compiler.source>
        <maven.compiler.target>18</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.9.3</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
                <dependencies>
                    <dependency>
                        <groupId>org.junit.platform</groupId>
                        <artifactId>junit-platform-surefire-provider</artifactId>
                        <version>1.3.2</version>
AnnaVin
Уровень 47
15 мая 2023, 14:34
Кто может объяснить что не так, все зависимости добавлены как в начале только junit 5.9.3, создано 2 класса помимо стандартного мэйна, калькулятор и калькулятортест, но когда ставлю над методами в калькулятор тест аннотацию @Test Idea предлагает импортить 4-й Junit как её заставить видеть 5-й ?
AnnaVin
Уровень 47
15 мая 2023, 14:46
Видимо тестовый класс можно создавать только в папке в пакете java который в пакете test, иначе просто не видит импортов.
AnnaVin
Уровень 47
15 мая 2023, 14:54
Не получается победить, сплошные ошибки. Теперь тесты из статьи не проходят. Выдают ошибки.
AnnaVin
Уровень 47
15 мая 2023, 14:58
И вот такую штуку выдаёт. 'java.lang.Object org.apache.maven.surefire.util.internal.StringUtils.requireNonNull(java.lang.Object)'
AnnaVin
Уровень 47
16 мая 2023, 05:57
Получилось с 4 JUnit'ом.
AnnaVin
Уровень 47
16 мая 2023, 12:28
C 5 тоже получилось, нужно было больше внимательности.
AnnaVin
Уровень 47
16 мая 2023, 12:31
Хотя если вставить в Pom.xml
<build>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
                <dependencies>
                    <dependency>
                        <groupId>org.junit.platform</groupId>
                        <artifactId>junit-platform-surefire-provider</artifactId>
                        <version>1.3.2</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
тогда выдаёт такую ошибку 'java.lang.Object org.apache.maven.surefire.util.internal.StringUtils.requireNonNull(java.lang.Object)'
AnnaVin
Уровень 47
16 мая 2023, 14:06
Короче для тех у кого не клеилось с тестами, как и у меня, вот содержание моего pom.xml с которым фаза тестов запускает мои тесты из каталога test/java
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>JUnit_acquaintance</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>19</maven.compiler.source>
        <maven.compiler.target>19</maven.compiler.target>
    </properties>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.9.3</version>
            <scope>test</scope>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.1.0</version>
            </plugin>
        </plugins>
    </build>

</project>
Eduard
Уровень 1
5 февраля 2023, 22:48
Вот решение если у вас тоже проблемы с совместимостью версий Maven Surefire 2.22.0 и выше
<dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>5.9.2</version>
      <scope>test</scope>
    </dependency>
</dependencies>
<build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <source>${maven.compiler.source}</source>
          <target>${maven.compiler.target}</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.0.0-M6</version>
      </plugin>
    </plugins>
</build>
p3rsonal
Уровень 35
1 декабря 2022, 14:21
По-моему в 5 JUnit не обязательно указывать `public` в методах. Еще встречал подход расписывания тестов подобным образом: // Arrange * тут код где мы подготавливаем данные * // Act * тут выполняется проверяемый метод * // Assert * тут ассерты * Imho, с этими комментариями легче читается код.
Владимир Чугуевец
Уровень 108
Expert
18 сентября 2022, 19:57
Этот плагин точно должен содержать зависимость? у меня idea ругается Кстати, если ты хочешь, чтобы Maven на этапе сборки (test stage) запустил твои тесты, то в pom.xml нужно добавить еще один фрагмент: <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.19.1</version> <dependencies> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-surefire-provider</artifactId> <version>1.3.2</version> </dependency> </dependencies> </plugin>
Евгений
Уровень 47
21 декабря 2022, 13:56
я вставил в <build> <plugins> ... </plugins> </build> после чего запустил авто-импорт в идеи, все заработало.
Stas S
Уровень 108
Expert
1 сентября 2022, 06:39
От куда информация про необходимость написания хотя бы 1 теста для каждого метода ? Если все делать по примеру из лекции, получаем WARNING: "The junit-platform-surefire-provider has been deprecated" Зачем нам устаревший плагин ? Проще воспользоваться этим
<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.2</version>
</plugin>
Musa MuradzadeQA Automation Engineer в IT-ONE
16 июня 2022, 22:14
IDEA ругалась на assertEquals(), мне помогло: 1) import static org.junit.Assert.*; 2) IDEA предложит добавить зависимость
<dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.13</version>
           <scope>test</scope>
</dependency>
3) Тесты без проблем запустились
Stas S
Уровень 108
Expert
1 сентября 2022, 06:34
Вы добавили JUnit 4 версии и сделали импорт от туда. Если использовать зависимость из лекции(JUnit 5), для работы нужны следующие импорты :
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;