簡體   English   中英

如何在 Junit 測試期間將日志級別設置為 DEBUG?

[英]How to set the log level to DEBUG during Junit tests?

我將 SLF4J 與 LOG4J 一起使用,配置通常在log4j.properties ,並將日志級別設置為 INFO。

但是在測試期間,我想將日志設置為 DEBUG。

我看不到自動化的方法,也沒有像log4j.tests.properties這樣只會在測試期間加載的東西。

所以我嘗試在測試設置(@BeforeClass)中以編程方式執行此操作:

LogManager.getRootLogger().setLevel(Level.ALL);

沒有成功...

我正在使用這些版本:

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.5</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.5</version>
    </dependency>

我怎樣才能達到這個結果?

編輯:我想我還不夠清楚。 這個問題不是關於設置正確的日志級別...而是關於在運行 Junit 測試時設置 DEBUG 日志級別,以及在任何其他情況下設置 INFO 日志級別。 我想自動化這個。

您不需要為 JVM 提供不同的日志實現。

日志代碼使用類路徑搜索log4j.properties文件。 所以您需要做的就是確保您的測試log4j.properties文件位於它會在發布文件之前找到的位置。

我使用 Maven,它在目錄中布置文件以簡化操作。 我的發行版log4j.properties位於src/main/resources目錄中。 我的測試版本在src/test/resources Eclipse 構建路徑(類路徑)設置為在src/main/resources之前搜索src/test/resources src/main/resources ,因此您的單元測試使用測試文件。 JAR(或 WAR)構建指令使用來自src/main/resources的文件。

您可以使用具有setAllLevels方法的org.apache.logging.log4j.core.config.Configurator

在您的測試中,您可以在@Before方法中使用它:

  @Before
  public void changeLogLevel() {
    Configurator.setAllLevels("", Level.ALL);
  }

注意:通過綁定測試org.slf4j:slf4j-log4j12:1.7.26

低於 ROOT 日志級別更改將適用於 junit 將日志記錄設置為所需級別。

import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;

@Before
public void setUp() {
    final Logger logger = (Logger)LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
    logger.setLevel(Level.ALL);
}

一開始可能與問題並不完全相關,但是當大多數開發人員搜索方法時,谷歌查詢會將他們引向這個主題

如何更改某些 junit 測試方法的日志級別。

要走的路是使用自定義 junit MethodRule 訪問記錄器並重新配置每個包的日志級別。

通過以下課程,您可以實現這一目標。 它按照測試方法的注釋中的定義設置包和類的日志級別,當測試完成時,將記錄器設置回它們的初始狀態。 我們假設默認日志級別當前設置為 INFO。

@Test
@LogLevel(packageToLevel = { "my.java.package=DEBUG", "my.other.java.package.ClassNeedsTracing=TRACE" })
public void allLogsOfThatPackageAreInDebugNow() {
   ...
}

@Test
@LogLevel(packageToLevel = { "my.java.package=TRACE", "my.java.package.ClassNoTracing=TRACE" })
public void allLogsOfThatPackageAreInTraceNowExceptOneClass() {
   ...
}

為此,您需要在測試類中指定測試規則:

@Rule
LogLevelRule logLevelRule = new LogLevelRule();

需要的課程如下:

import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.junit.rules.MethodRule;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;

/**
 * a Junit Rule that check for LogLevel annotation on methods and activates the configured log level per package. After
 * the test was executed, restores the previous log level.
 */
public class LogLevelRule implements MethodRule {

    @Override
    public Statement apply(Statement base, FrameworkMethod method, Object target) {

        return new Statement() {
            @Override
            public void evaluate() throws Throwable {

                // activate log level desired, remember what they were
                Map<String, Level> existingPackageLogLevel = new HashMap<>();
                LogLevel logLevelAnnotation = method.getAnnotation(LogLevel.class);
                if (logLevelAnnotation != null) {
                    activate(logLevelAnnotation.packageToLevel(), existingPackageLogLevel);
                }

                // run the test
                Throwable testFailure = evaluateSafely(base);

                // revert the log level back to what it was
                if (!existingPackageLogLevel.isEmpty()) {
                    deactivate(existingPackageLogLevel);
                }

                if (testFailure != null) {
                    throw testFailure;
                }
            }

            /**
             * execute the test safely so that if it fails, we can still revert the log level
             */
            private Throwable evaluateSafely(Statement base) {
                try {
                    base.evaluate();
                    return null;
                } catch (Throwable throwable) {
                    return throwable;
                }
            }
        };
    }

    /**
     * activates the log level per package and remember the current setup
     *
     * @param packageToLevel
     *            the configuration of the annotation
     * @param existingPackageLogLevel
     *            where to store the current information
     */
    protected void activate(String[] packageToLevel, Map<String, Level> existingPackageLogLevel) {
        for (String pkgToLevel : packageToLevel) {
            String[] split = pkgToLevel.split("=");
            String pkg = split[0];
            String levelString = split[1];
            Logger logger = LogManager.getLogger(pkg);
            Level level = logger.getLevel();
            existingPackageLogLevel.put(pkg, level);
            logger.setLevel(Level.toLevel(levelString));
        }
    }

    /**
     * resets the log level of the changes packages back to what it was before
     *
     * @param existingPackageLogLevel
     */
    protected void deactivate(Map<String, Level> existingPackageLogLevel) {
        for (Map.Entry<String, Level> e : existingPackageLogLevel.entrySet()) {
            LogManager.getLogger(e.getKey()).setLevel(e.getValue());
        }
    }

}




import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * marks a method to use a different log level for the execution phase
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface LogLevel {
    String[] packageToLevel();
}

通常 LEVEL.FINEST 應該這樣做......但請查看http://saltnlight5.blogspot.mx/2013/08/how-to-configure-slf4j-with-different.html以查看日志框架實現考慮。

如前所述,logback 系統使用src/test/resources/logback-test.xml文件來配置單元測試日志級別。 這是一個示例文件:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
    <appender name="ConsoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
        </encoder>
    </appender>

    <root>
        <level value="DEBUG" />
        <appender-ref ref="ConsoleAppender" />
    </root>

    <logger name="com.example.report" level="TRACE" additivity="false">
        <appender-ref ref="ConsoleAppender" />
    </logger>

</Configuration>

在此示例中,根(默認)日志級別設置為DEBUG com.example.report包中的類在TRACE級別及以下記錄它們的消息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM