Статьи

Модульное тестирование с помощью JUnit с использованием Maven и IntelliJ — Часть 1

Модульное тестирование — это первый уровень  тестирования программного обеспечения,  где вы пишете тестовый код, который выполняет определенные функции в тестируемом коде. В большинстве случаев вы, как программист, несете ответственность за предоставление кода, проверенного модулем. Цель состоит в том, чтобы проверить, ведет себя ли модуль программного обеспечения, например, открытый метод тестируемого класса, как ожидалось, и / или возвращает ожидаемые данные. Модульные тесты  не сделано в производственной системе, но как отдельные единицы. Если у тестируемого модуля есть внешние зависимости, такие как внешний источник данных или веб-служба, зависимости заменяются реализацией теста или фиктивным объектом, созданным с использованием инфраструктуры тестирования. Модульное тестирование — не единственный тип, и оно само по себе не может охватить все аспекты тестирования. Другие типы тестирования, такие как интеграционное и функциональное тестирование, играют свою роль в тестировании программного обеспечения.

В этой серии статей мы сосредоточимся на модульном тестировании с помощью JUnit — одного из самых популярных фреймворков для тестирования кода Java. В этой статье мы начнем с создания и выполнения базового модульного теста, а затем в других публикациях перейдем к конкретным аспектам модульного тестирования.

Базовая среда JUnit поставляется в одном JAR-файле, который вы можете загрузить, указать ему путь к классу, а затем создать и запустить тесты. Но в этом посте мы узнаем, как выполнять модульное тестирование в режиме реального программиста. Мы начнем с Maven, а затем перейдем к IntelliJ.

Модульное тестирование с Maven

Вы, вероятно, слышали, что Maven называют инструментом для сборки. Но в дополнение к своей способности создавать развертываемые артефакты из исходного кода, Maven предоставляет ряд функций для управления жизненным циклом разработки программного обеспечения. Модульное тестирование является одной из таких функций, которая включена в качестве фазы тестирования в  жизненный цикл сборки Maven .

Не углубляясь в Maven, давайте начнем наш первый тест JUnit с Maven.

    1. Загрузите и установите Maven,  если вы еще этого не сделали.
    2. Откройте командную строку (Windows) или терминал (* uix или Mac), найдите рабочий каталог для настройки проекта и выполните следующую команду.
mvn archetype:generate -DgroupId=guru.springframework.unittest.quickstart -DartifactId=unittest -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

Предшествующая  archetype:generate команда использует  maven-archetype-quickstart шаблон для создания базового проекта Maven , содержащего  pom.xml  файл,  App.java  класс, и  AppTest.java  тестового класс в следующей структуре каталогов.

└───pom.xml      
└───src
    ├───main
    │   └───java
    │       └───guru
    │           └───springframework
    │               └───unittest
    │                   └───quickstart
    │                           App.java
    └───test
        └───java
            └───guru
                └───springframework
                    └───unittest
                        └───quickstart
                                AppTest.java

В приведенной выше структуре  каталогов  файл pom.xml , также известный как файл конфигурации Maven, является сердцем проекта Maven. Именно здесь вы определяете конфигурации вашего проекта — в частности, зависимости вашего проекта. Например, поскольку наш проект зависит от JUnit, мы должны объявить его как зависимость в  файле pom.xml . Хотя зависимость JUnit уже будет присутствовать по умолчанию, мы обновим ее, чтобы она указала на последнюю версию JUnit. Вот так  будет выглядеть наш последний  файл pom.xml .

pom.xml:

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>guru.springframework.unittest.quickstart</groupId>
  <artifactId>unittest</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>unittest</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>4.12</version>
     <scope>test</scope>
    </dependency>
      <dependency>
          <groupId>org.hamcrest</groupId>
          <artifactId>hamcrest-library</artifactId>
          <version>1.3</version>
          <scope>test</scope>
      </dependency>
  </dependencies>
</project>

Теперь, когда мы настроили базовый класс Java, тестовый класс и   конфигурацию pom.xml , мы можем запустить модульный тест.

    1. Выполните  mvn test команду из рабочего каталога.

Эта команда запустит AppTest класс по умолчанию  , сгенерированный для нас Maven со следующим выводом.

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running guru.springframework.unittest.quickstart.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.043 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.691 s
[INFO] Finished at: 2015-06-18T20:16:34+05:30
[INFO] Final Memory: 14M/136M
[INFO] ------------------------------------------------------------------------ 

Мы выполнили тест JUnit, используя Maven. Этот тест пройден, но вряд ли дает какое-либо значение. Далее мы перейдем к использованию IntelliJ IDE для написания и выполнения более полного теста.

Модульное тестирование в IntelliJ

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

Давайте импортируем наш существующий проект Maven в IntelliJ и проведем некоторое модульное тестирование.

Импортировать Maven Project в IntelliJ

Если у вас не установлен IntelliJ, загрузите и установите бесплатную версию Community Edition или 30-дневную пробную версию Ultimate Edition с  официального сайта . Как только вы закончите, выполните следующие действия:

    1. Откройте IntelliJ.
    2. В окне  Добро пожаловать в IntelliJ IDEA  нажмите  Импортировать проект .

Нажмите Импортировать проект

    1. В  диалоговом окне «  Выбрать файл или каталог для импорта » перейдите к рабочему каталогу проекта Maven и выберите   файл pom.xml .

Выберите pom.xml

    1. Нажмите  кнопку ОК  .
    2. В открывшемся  диалоговом окне «  Импорт проекта из Maven » установите флажок «  Импорт проектов Maven автоматически»,  чтобы синхронизировать изменения между проектами Maven и InteliiJ при каждом  изменении файла pom.xml .

Установите флажок Импортировать проекты Maven автоматически

    1. Нажмите  кнопку Далее  через несколько диалоговых окон, принимая настройки по умолчанию, и, наконец, нажмите Готово . Окно  Project  IntelliJ отображает структуру проекта.

Структура структуры в проекте IntelliJ.

  1. Дважды щелкните  App  в   окне Project, чтобы открыть его в редакторе кода.
  2. Замените код App класса по умолчанию  этим кодом.

app.java:

package guru.springframework.unittest.quickstart;


public class App
{
    public String concatAndConvertString(String str1, String str2){
        String concatedString=str1.concat(str2);
        return concatedString.toUpperCase();
    }
    }

В приведенном выше коде мы написали  concatAndConvertString() метод в  App классе, который принимает два  String параметра. Метод сначала объединяет строки и преобразует результат в верхний регистр, а затем возвращает его.

Затем мы добавим тестовый класс для тестирования  concatAndConvertString() метода.

Добавить тестовый класс

Давайте пройдемся по шагам, чтобы добавить тестовый класс в IntelliJ с нуля.

    1. Удалите  класс AppTest по умолчанию  из   окна проекта .
    2. В   окне Project создайте каталог с именем  test  в  main. Мы будем использовать   каталог test, чтобы отделить тестовый код от кода приложения.
    3. Щелкните правой кнопкой мыши  тест  и выберите  Пометить каталог как → Тестировать корень источника .

выберите «Пометить каталог как», а затем «Тестировать корневые источники»

    1. В редакторе кода, в котором открыт   класс App , нажмите  Shift+F10 и выберите «  Создать новый тест» .

Выберите Создать новый тест

    1. В открывшемся  диалоговом окне «  Создать тест » выберите переключатель  jUnit4  и флажок, соответствующий  методу concatAndConvertString (),  который мы будем тестировать.

Выберите переключатель jUnit4 и метод, который мы будем тестировать

  1. Нажмите   кнопку ОК . JUnit создает   класс AppTest с  testConcatAndConvertString()методом, украшенным  @Test аннотацией. Эта аннотация говорит JUnit запускать метод как тестовый пример. В методе test мы напишем код для проверки  concatAndConvertString() метода  App .

AppTest.Java:

package guru.springframework.unittest.quickstart;
import org.junit.Test;
import static org.junit.Assert.*;

public class AppTest {

   @Test
    public void testConcatAndConvertString() throws Exception {
       String expectedValue="HELLOWORLD";
       App app=new App();
       String actualValue=app.concatAndConvertString("Hello", "World");
       assertEquals(expectedValue, actualValue);
    }
}

В строке 12 приведенного выше примера мы назвали  assertEquals() метод, который является одним из нескольких методов утверждения JUnit. Этот перегруженный метод проверяет, String равны ли два  объекта. Если они не, метод бросает  AssertionError. В нашем примере мы вызвали  assertEquals() метод, передав ожидаемое строковое значение ( HELLOWORLD) в качестве первого параметра и фактическое значение, которое  concatAndConvertString() метод возвращает в качестве второго параметра.

Запустите юнит-тест

Чтобы запустить тест, выберите «  Запустить AppTest»  в меню «Выполнить» IntelliJ или нажмите  Shift + F10 . Окно  Run  отображает результат теста. Зеленое поле выделения указывает на то, что тест завершен без ошибок.

Зеленое поле выделения, указывающее пройденный тест

Чтобы узнать, как сообщается об ошибках теста, измените значение  expectedValueпеременной на  HelloWorldи нажмите  Shift + F10 . В  диалоговом окне «  Выполнить » отображается красный индикатор выполнения, указывающий на сбой теста, а также сообщение о сбое сравнения.

Красный индикатор выполнения, указывающий на неудачный тест

Верните  expectedValue переменную к ее первоначальному значению, прежде чем закрыть IntelliJ.

Резюме

На данный момент, если вы думаете,  почему бы просто не использовать System.out.println () для модульного тестирования?  Тогда вы думаете неправильно. Вставка  System.out.println ()  для отладки в код нежелательна, поскольку требует ручного сканирования выходных данных при каждом запуске программы, чтобы гарантировать, что код выполняет то, что ожидается. Представьте, что вы делаете это в корпоративном приложении, содержащем сотни и тысячи строк кода. С другой стороны, модульные тесты исследуют поведение кода во время выполнения с точки зрения клиента. Это позволяет лучше понять, что может произойти при выпуске программного обеспечения.

Всякий раз, когда вы пишете код, вы должны также писать модульные тесты. Написание модульных тестов позволит выявлять ошибки программирования и улучшать качество вашего кода. Многие профессиональные разработчики выступают за разработку Test Driven Development (TDD), где вы пишете свои модульные тесты перед написанием кода приложения.

В любом случае, если вы пишете свои модульные тесты до или после написания кода приложения, модульные тесты становятся ценным ресурсом для инструментария вашего кода. По мере роста базы кода вы можете реорганизовывать вещи по мере необходимости и иметь больше уверенности в том, что ваши изменения не будут иметь непредвиденных последствий (т. Е. Когда вы меняете одну вещь и случайно ломаете другую).

Во  второй части моей серии руководств по модульному тестированию с JUnit  я более подробно рассмотрю утверждения JUnit, аннотации JUnit и наборы тестов JUnit.

Модульное тестирование с Spring Framework

Тестирование является неотъемлемой частью процесса разработки  корпоративных приложений  с помощью Spring Framework. Архитектура Spring Framework предоставляет модульный код и упрощает модульное тестирование. Spring предоставляет поддержку тестирования через TestContext Framework, который абстрагирует базовую среду тестирования, такую ​​как JUnit и TestNG. Вы можете использовать его, установив SpringJUnit4ClassRunner.class в качестве значения для аннотации @RunWith. Это говорит Spring, чтобы использовать тестовый прогон TestContext вместо встроенного в JUnit тестового прогона. Я написал более подробный пост о тестировании приложений Spring с JUnit  здесь .