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

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

JSP & Servlets
3 уровень , 1 лекция
Открыта

Подключаем фреймворк 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)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Алексей Уровень 27
16 декабря 2024
Может я че пропустил но где рассказывали что в plugins можно dependecies засовывать и в чем смысл?
Олег Уровень 106 Expert
1 августа 2024
dependency Выделило красным в pom. Что делать?
Рубен Уровень 80
20 сентября 2024
проверять синтаксис
Taurnil Уровень 107 Expert
31 января 2024

<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 Уровень 2 Expert
15 июля 2023
А вот мне интересно.... только у меня работает сборка проекта только через 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 Уровень 2 Expert
16 июля 2023
разобралась, если у вас выскакивает ошибка:

'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 Уровень 2 Expert
16 июля 2023

<?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
Кто может объяснить что не так, все зависимости добавлены как в начале только junit 5.9.3, создано 2 класса помимо стандартного мэйна, калькулятор и калькулятортест, но когда ставлю над методами в калькулятор тест аннотацию @Test Idea предлагает импортить 4-й Junit как её заставить видеть 5-й ?
AnnaVin Уровень 47
15 мая 2023
Видимо тестовый класс можно создавать только в папке в пакете java который в пакете test, иначе просто не видит импортов.
AnnaVin Уровень 47
15 мая 2023
Не получается победить, сплошные ошибки. Теперь тесты из статьи не проходят. Выдают ошибки.
AnnaVin Уровень 47
15 мая 2023
И вот такую штуку выдаёт. 'java.lang.Object org.apache.maven.surefire.util.internal.StringUtils.requireNonNull(java.lang.Object)'
AnnaVin Уровень 47
16 мая 2023
Получилось с 4 JUnit'ом.
AnnaVin Уровень 47
16 мая 2023
C 5 тоже получилось, нужно было больше внимательности.
AnnaVin Уровень 47
16 мая 2023
Хотя если вставить в 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
Короче для тех у кого не клеилось с тестами, как и у меня, вот содержание моего 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 Уровень 41
5 февраля 2023
Вот решение если у вас тоже проблемы с совместимостью версий 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
По-моему в 5 JUnit не обязательно указывать `public` в методах. Еще встречал подход расписывания тестов подобным образом: // Arrange * тут код где мы подготавливаем данные * // Act * тут выполняется проверяемый метод * // Assert * тут ассерты * Imho, с этими комментариями легче читается код.
Владимир Чугуевец Уровень 108 Expert
18 сентября 2022
Этот плагин точно должен содержать зависимость? у меня 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
я вставил в <build> <plugins> ... </plugins> </build> после чего запустил авто-импорт в идеи, все заработало.
Stas S Уровень 108 Expert
1 сентября 2022
От куда информация про необходимость написания хотя бы 1 теста для каждого метода ? Если все делать по примеру из лекции, получаем WARNING: "The junit-platform-surefire-provider has been deprecated" Зачем нам устаревший плагин ? Проще воспользоваться этим

            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
            </plugin>
Musa Muradzade Уровень 1
16 июня 2022
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
Вы добавили JUnit 4 версии и сделали импорт от туда. Если использовать зависимость из лекции(JUnit 5), для работы нужны следующие импорты :

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;