Unit тесты в Java. Краткое руководство

Unit тесты в Java. Краткое руководство

  • 25 сентября, 2023
Платон Цыбульский
Платон Цыбульский Java developer в Brain agency

Каждая выполненная задача в программировании требует тестирования, потому что от ошибок, как известно, никто не застрахован.

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

А что если ваше приложение большое и в нем много зависящих друг от друга модулей, классов и компонент, и ваша задача — изменить поведение существующего кода, при этом не повредив старое?

В чем смысл Unit-тестов?

Именно для этого придумали юнит тесты, которые дают возможность автоматизировать проверку приложения.

Но ведь на написание тестов тоже уходит время — возразите вы и будете правы. Дело в том, что с ростом вашего приложения это время будет сокращаться, а без тестов ситуация обратная: чем сложнее становится приложение, тем более трудоемким будет его изменение и процесс отслеживания ошибок.

К тому же, не будем забывать, что интеграционное тестирование, которым пользуется большинство «смертных» программистов, требует запуска приложения, а, как известно из основ программирования Java, в Java развертывание и сборка — процесс не самый быстрый.

Помнится мне один банковский проект, в котором я тратил на это 15 минут, но не будем о грустном.

Для того, чтобы проникнуться данной концепцией, предлагаю почитать об экстремальном программировании. А пока давайте рассмотрим, какие инструменты нам предлагает Java для решения этой проблемы, и о том, как создать тест на Java.

Наиболее популярные — JUnit и TestNg, и речь сегодня пойдет о первом. Он является простым и гибким фреймворком для тестирования.

Рекомендуем курс по теме

JUnit аннотации и их описание

Пример Unit теста

Для того, чтобы подключить JUnit, нам необходимо добавить dependency в pom.xml, на момент написания статьи самая свежая версия 4.12:

Затем представим, для простоты понимания, что у нас есть класс калькулятор, который может прибавлять и вычитать:

Unit тест для такого класса будет выглядеть так:

  • Размещаться данный класс должен в папке test, которая специально создана для хранения тестовых классов.
  • Название класса должно соответствовать одной из масок: *Test, Test*, *TestCase для того, чтобы maven surefire plugin смог найти ваш тестовый класс.
  • Методы должны иметь возвращаемый тип void в сигнатуре и аннотацию @Test, которая определяет, что метод является тестовым.
  • Аннотация @Beforeуказываетна то, что метод будет выполняться перед каждым тестируемым методом.

Также для проверки результата используется специальный проверяемый метод assertEquals, который в нашем случае может принимать сообщение, которое будет показываться при несоответствии фактического и ожидаемого результата, затем второй параметр – фактический результат и третий ожидаемый результат.

Далее открываем терминал, перейдем в папку с нашим проектом и выполним mvn test:

По выводу лога консоли видно, что тесты прошли успешно. Если же мы изменим знак в методе add c + на *, то тест будет failed, и лог будет выглядеть так:

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

Рекомендуем курс по теме

В следующей таблице приведен обзор имеющихся в аннотации JUnit 4.x.

Аннотация Описание
@Test public void method() public void method() public void method() public static void method() public static void method() Аннотация @Test определяет что метод method() является тестовым.
@Before Аннотация @Before указывает на то, что метод будет выполнятся перед каждым тестируемым методом @Test.
@After Аннотация @After указываетна то что метод будет выполнятся после каждого тестируемого метода @Test
@BeforeClass Аннотация @BeforeClass указывает на то, что метод будет выполнятся в начале всех тестов, а точней в момент запуска тестов(перед всеми тестами @Test).
@AfterClass Аннотация @AfterClass указывает на то, что метод будет выполнятся после всех тестов.
@Ignore Аннотация @Ignore говорит, что метод будет проигнорирован в момент проведения тестирования.
@Test (expected = Exception.class) (expected = Exception.class) — указывает на то, что в данном тестовом методе вы преднамеренно ожидается Exception.
@Test (timeout=1000) (timeout=1000) — указывает, что тестируемый метод не должен занимать больше чем 1 секунду.

Проверяемые методы (основные)

Метод Описание
fail(String) Указывает на то что бы тестовый метод завалился при этом выводя текстовое сообщение.
assertTrue([message], boolean condition) Проверяет, что логическое условие истинно.
assertsEquals([String message], expected, actual) Проверяет, что два значения совпадают. Для массивов проверяются ссылки, а не содержание массивов.
assertNull([message], object) Проверяет, что объект является пустым null.
assertNotNull([message], object) Проверяет, что объект не является пустым null.
assertSame([String], expected, actual) Проверяет, что обе переменные относятся к одному объекту.
assertNotSame([String], expected, actual) Проверяет, что обе переменные относятся к разным объектам.

Также я прикрепил пример с ООП моделью компании, в которой подсчитываются затраты на зарплату для сотрудников по компании и департаменту.

Основные методы покрыты unit тестами, код размещен тут.

Нажимай и выигрывай от
1 000 до 5 000 ₴