![](/img/trans.png)
[英]How do I turn off/change the log level of dozer during unit tests with standard java logging?
[英]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.