Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Запуск тестов и чтение результатов

Тест полезен, только если его часто запускать и понимать, что он говорит. В этом уроке — как запустить из терминала все тесты или только часть и как читать отчёт Maven: и когда всё прошло, и когда что-то сломалось.

Все тесты

В папке проекта (там, где pom.xml):

mvn test

Maven компилирует код и тесты, а Surefire запускает каждый тестовый класс:

[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.example.shop.PriceCalculatorTest
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.004 s -- in com.example.shop.PriceCalculatorTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] BUILD SUCCESS
СчётчикСмысл
Tests runСколько тестов выполнено
FailuresПроверка не выполнилась: результат отличается от ожидаемого
ErrorsТест упал с неожиданным исключением, например NullPointerException
SkippedТест отключён или пропущен из-за допущения

Часть тестов

mvn test -Dtest=PriceCalculatorTest              # один класс
mvn test -Dtest='PriceCalculatorTest#discount*'  # методы по шаблону
mvn test -Dtest='Price*'                         # классы по шаблону

Кавычки защищают # и * от командной оболочки. В IntelliJ IDEA то же самое делает зелёная стрелка рядом с классом или методом.

Упавший тест

Допустим, автор теста ошибся в расчёте и ждёт $40.00 после скидки 10% с $50.00. Добавим ещё тест, который вызывает total() с количеством -1 и не ожидает исключения:

// src/test/java/com/example/shop/PriceCalculatorTest.java
@Test
void negativeQuantity() {
    PriceCalculator calculator = new PriceCalculator();
 
    calculator.total(new BigDecimal("12.00"), -1);
}

Вывод mvn test (строки стека самого JUnit убраны):

[ERROR] Tests run: 3, Failures: 1, Errors: 1, Skipped: 0, Time elapsed: 0.150 s <<< FAILURE! -- in com.example.shop.PriceCalculatorTest
[ERROR] com.example.shop.PriceCalculatorTest.negativeQuantity -- Time elapsed: 0.085 s <<< ERROR!
java.lang.IllegalArgumentException: Количество должно быть больше нуля: -1
	at com.example.shop.PriceCalculator.total(PriceCalculator.java:10)
	at com.example.shop.PriceCalculatorTest.negativeQuantity(PriceCalculatorTest.java:33)
 
[ERROR] com.example.shop.PriceCalculatorTest.discountReducesAmount -- Time elapsed: 0.009 s <<< FAILURE!
org.opentest4j.AssertionFailedError: expected: <40.00> but was: <45.00>
	at com.example.shop.PriceCalculatorTest.discountReducesAmount(PriceCalculatorTest.java:26)
 
[INFO] Results:
[ERROR] Failures:
[ERROR]   PriceCalculatorTest.discountReducesAmount:26 expected: <40.00> but was: <45.00>
[ERROR] Errors:
[ERROR]   PriceCalculatorTest.negativeQuantity:33 » IllegalArgument Количество должно быть больше нуля: -1
[ERROR] Tests run: 3, Failures: 1, Errors: 1, Skipped: 0
[INFO] BUILD FAILURE

Читайте сверху: класс и метод, FAILURE или ERROR, сообщение и строка в файле теста. Падение (failure) — это expected ... but was ...: решите, кто неправ, код или тест. Здесь неправ тест: 10% от $50.00 — это $5.00, значит, результат $45.00. Ошибка (error) значит, что код выбросил исключение, которого тест не ждал; стек показывает, где именно. Как проверять исключения намеренно — в следующей главе.

Полные отчёты по каждому классу сохраняются в target/surefire-reports: файл .txt с тем же текстом и .xml, который читают CI-серверы.

Какие классы считаются тестами

По умолчанию Surefire запускает классы, имена которых подходят под шаблоны:

ШаблонПример
**/Test*.javaTestPriceCalculator
**/*Test.javaPriceCalculatorTest
**/*Tests.javaPriceCalculatorTests
**/*TestCase.javaPriceCalculatorTestCase

Класс PriceCalculatorCheck скомпилируется, но Maven его никогда не запустит. IDE при этом запускает его, так что ошибка остаётся незамеченной до CI.

Частая ошибка

Опечатка в -Dtest останавливает сборку:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.6.0:test (default-test) on project blog: No tests matching pattern "PriceCalculatorTests" were executed! (Set -Dsurefire.failIfNoSpecifiedTests=false to ignore this error.) -> [Help 1]

Класс называется PriceCalculatorTest, без s. Проверьте имя: шаблон должен совпадать с простым именем класса.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.