Статьи

Учебник: ведение журнала во время тестов

Ведение журнала является популярным решением для демонстрации того, что программное обеспечение делает во время работы.

Но что происходит с журналированием, когда мы тестируем наше приложение с помощью jUnit / TestNG?

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

Было бы неплохо иметь возможность отключить регистрацию сообщений во время стандартных автоматических тестов.

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

Таким образом, мы можем выделить три варианта использования:

  1. Режим работы , когда приложение выполняется: ведение журнала включено и настроено в соответствии с требованиями приложения
  2. Тестовый режим выполнения , когда автоматизированные тесты выполняются все вместе: протоколирование сообщений должно быть отключено
  3. Тестовый режим создания , когда мы создаем новые тесты: сообщения регистрации полезны, но было бы хорошо иметь их в консоли

Давайте посмотрим на пример, основанный на Maven и SLF4J , популярном фасаде.

  • Полный проект можно найти здесь .

Типичная конфигурация SLF4J в проекте pom.xml следующая:

01
02
03
04
05
06
07
08
09
10
11
<dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
            <scope>runtime</scope>
        </dependency>

зависимость slf4-api является основной библиотекой SLF4J, а вторая, slf4j-log4j12 , ссылается на один из возможных механизмов ведения журналов ( LOG4J ), который может работать ниже SLF4J.

Это конфигурация режима работы . В этом примере ресурсы проекта будут содержать файл свойств LOG4J, который определяет, что, как и где LOG4J должен регистрировать.

Та же самая ситуация происходит, когда мы используем другой механизм ведения журнала, такой как java.util.logging (JDK) и Logback. Смотрите руководство Slf4J для более подробной информации.

В режиме выполнения теста нам не нужна регистрация, поэтому мы можем просто добавить следующую зависимость теста области

1
2
3
4
5
6
<dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>${slf4j.version}</version>
            <scope>test</scope>
        </dependency>

Регистратор NOP (slf4j-nop) просто отбрасывает все записи.

Важно : порядок зависимостей в pom.xml является значительным. Поместите зависимость slf4j-nop сразу после зависимости slf4-api чтобы она использовалась во время тестов, даже если в зависимости есть другой механизм ведения журнала.

Когда в pom.xml pom.xml есть несколько зависимостей от pom.xml , SLF4J все равно покажет сообщение, подобное следующему:

1
2
3
4
5
SLF4J: Class path contains multiple SLF4J bindings.
    SLF4J: Found binding in [jar:file:.m2/repository/org/slf4j/slf4j-nop/1.7.12/slf4j-nop-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: Found binding in [jar:file:.m2/repository/org/slf4j/slf4j-log4j12/1.7.12/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
    SLF4J: Actual binding is of type [org.slf4j.helpers.NOPLoggerFactory]

Подводя итог, можно привести полный пример конфигурации:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>${slf4j.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
            <scope>runtime</scope>
        </dependency>

Опять же, последняя зависимость должна быть скорректирована в соответствии с желаемым механизмом ведения журнала.

Как я уже упоминал ранее, регистрация может быть полезна при создании новых тестов. В этом случае ( тестовый режим создания ) мы можем временно заменить slf4j-nop slf4j-simple которая включает простой регистратор SLF4J .

Сообщения журнала теперь будут отображаться в окне консоли во время выполнения тестов как сообщения System.err . Файл конфигурации не требуется.

По умолчанию Simple logger не регистрирует сообщения отладки. Стандартный уровень ведения журнала — INFO.

Вы можете настроить поведение Simple logger, используя системные переменные, описанные здесь .

Умный способ определить конфигурацию Simple logger — использовать [раздел конфигурации плагина Surefire] ( http://maven.apache.org/surefire/maven-surefire-plugin/examples/system-properties.html ):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.18.1</version>
                <configuration>
                    <systemPropertyVariables>
                        <org.slf4j.simpleLogger.defaultLogLevel>DEBUG</org.slf4j.simpleLogger.defaultLogLevel>
                        <org.slf4j.simpleLogger.showDateTime>true</org.slf4j.simpleLogger.showDateTime>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
        </plugins>
    </build>

В разделе systemPropertyVariables мы можем создать теги с именем переменной Simple logger. В приведенном выше примере включены протоколы DEBUG и timestamp.