Утверждения (Asserts)

Каждую проверку, которую мы написали для функции capitalize(), в тестировании принято называть утверждением (assert). Утверждения — ключевая часть тестов. Именно они проверяют функциональность кода:

import static hexlet.Capitalize.capitalize;

// Первое утверждение (проверка на пустую строку)
if (!"".equals(capitalize(""))) {
    throw new AssertionError("Метод работает неверно!");
}

// Второе утверждение (проверка на слово)
if (!"Hello".equals(capitalize("hello"))) {
    throw new AssertionError("Метод работает неверно!");
}

Можно заметить, что все проверки строятся одинаковым способом: условие => исключение. Java, начиная с версии 1.4., обладает ключевым словом assert, которое предназначено для проверки утверждений:

// Проверка сменилась с отрицательной на положительную
assert 4 == 2 + 2;
assert "".equals(capitalize(""));
assert "Hello".equals(capitalize("hello")) : "Ваш метод не работает!";

Синтаксис достаточно прост:

  1. указываем ключевое слово assert,
  2. пишем выражение или вызываем метод, результатом которого будет булево выражение (true или false),
  3. опционально: после двоеточия можем указать некоторое строковое сообщение, которое будет передано вместе с ошибкой. В общем случае может быть не просто строка, а любое выражение, которое возвращает что-то отличное от void.

В случае если значение после ключевого слова assert будет равно false, то будет выброшено исключение AssertionError. Другими словами, assert true означает что всё хорошо, а assert false говорит об ошибке. Например, если в последнем примере метод capitalize("hello") вернёт что-то отличное от Hello, то мы увидим в консоли вот такое сообщение:

java.lang.AssertionError: Ваш метод не работает!

    at hexlet.LessonTest.mainTest(LessonTest.java:12)
    ...

В первой строке мы видим какое исключение было проброшено (java.lang.AssertionError) и сообщение, которое мы передали вместе с ним. Кроме сообщения, выводится бектрейс, по которому можно найти сработавшее утверждение. В данном случае необходимо изучать код на 12 строке в классе hexlet.LessonTest.java.

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

Однако, ключевое слово assert было введено только в Java 1.4., это значит что в предыдущих версиях Java вполне можно было создать переменную или метод с именем assert. Программы в которых использовались такие имена могли стать неработоспособными после введения нового ключевого слова. Для сохранения обратной совместимости было принято решение, что по умолчанию механизм использования assert будет отключен. Если нужно чтобы ваши assert срабатывали, то при запуске программы указывается аргумент командной строки -enableassertions (-ea).

Рассмотрим пример. Допустим у нас есть вот такой класс:

public class HelloWorld {

    public static void main(String... args) {
        assert 1 == 2; // заведомо ложное утверждение
        System.out.println("Hello world");
    }
}

Если мы его скомпилируем и запустим без дополнительных аргументов, то мы увидим на экране текст Hello world, несмотря на то, что 1 точно не равно 2. Чтобы включить assert нам необходимо сделать так:

$ javac HelloWorld.java
$ java -ea HelloWorld

Тогда в консоли вместо надписи Hello world мы увидим сообщение об ошибке:

Exception in thread "main" java.lang.AssertionError
    at HelloWorld.main(HelloWorld.java:4)

В практиках используется Maven, для включения срабатываний assert мы прописываем специальную переменную окружения командой:

export MAVEN_OPTS="-ea"
Мы учим программированию с нуля до стажировки и работы. Попробуйте наш бесплатный курс «Введение в программирование» или полные программы обучения по Javascript, PHP, Python и Java.

Хекслет

Подробнее о том, почему наше обучение работает →