测试期间的日志记录和预期异常
Logging and expected Exceptions during testing
在我的应用程序代码中,在应用程序使用过程中出现问题的情况很常见,我希望尽可能多地记录有关情况的信息,如果适用,包括 Exception
的堆栈跟踪抛出。
但在测试期间,我不希望记录这些堆栈跟踪,从而毫无意义地将日志文件弄得乱七八糟。
如果在这种情况下,测试本身会创建一个 Exception
对象,您可以给它一条消息,将其标识为虚拟对象 Exception
,如下所示:
given:
indexMgr.queryParser = Mock( QueryParser ){
parse(_) >> { throw new Exception( 'dummy parse problem' )}
}
然后在应用代码中执行此操作:
try {
query = queryParser.parse(queryString)
}catch( e ) {
log.debug( "QP exception msg: $e.message" )
// we don't want a stack trace to be logged if this is a dummy Exception deliberately thrown during testing
if( ! e.message.contains( 'dummy' )) {
// this will log the stack trace of e
log.error( 'query threw Exception in QP.parse()', e )
}
return false
}
...但这有两个问题:首先,预期的 Exception
并不总是由测试代码而非应用程序代码创建的情况,其次,它在实际应用程序代码中检查识别测试行为的条件是错误的。
有"best practice"解决这个问题的方法吗?
如果只从一行中删除堆栈跟踪就可以了,您可以在记录器的模式布局中配置异常转换逻辑。下面是一个使用 log4j2 的例子:
public class ExceptionOutput {
private static final Logger LOG = LoggerFactory.getLogger(ExceptionOutput.class);
public static void main(String[] args) {
LOG.info("Foo", new NullPointerException("MESSAGE"));
}
}
log4j2 配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
alwaysWriteExceptions="false"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
注意 alwaysWriteExceptions=false
。它完全禁用异常输出。现在如果我们 运行 我们将得到的代码:
01:04:50.151 [main] INFO ExceptionOutput - Foo
但是如果你恢复到 alwaysWriteExceptions=true
,这也是省略参数时的默认行为,那么你会得到:
01:07:03.018 [main] INFO ExceptionOutput - Foo
java.lang.NullPointerException: MESSAGE
at ExceptionOutput.main(ExceptionOutput.java:8)
但还有更多。为了获得更大的灵活性,您可以在模式中使用 %throwable{...}
转换词,如 here in the Patterns table for the respective conversion pattern. In order to apply the logic only to tests you can have log4j2-test.xml on your classpath as explained here. Similar functionality of exceptions conversion also exists for other logging libraries, e.g. logback
所述
在我的应用程序代码中,在应用程序使用过程中出现问题的情况很常见,我希望尽可能多地记录有关情况的信息,如果适用,包括 Exception
的堆栈跟踪抛出。
但在测试期间,我不希望记录这些堆栈跟踪,从而毫无意义地将日志文件弄得乱七八糟。
如果在这种情况下,测试本身会创建一个 Exception
对象,您可以给它一条消息,将其标识为虚拟对象 Exception
,如下所示:
given:
indexMgr.queryParser = Mock( QueryParser ){
parse(_) >> { throw new Exception( 'dummy parse problem' )}
}
然后在应用代码中执行此操作:
try {
query = queryParser.parse(queryString)
}catch( e ) {
log.debug( "QP exception msg: $e.message" )
// we don't want a stack trace to be logged if this is a dummy Exception deliberately thrown during testing
if( ! e.message.contains( 'dummy' )) {
// this will log the stack trace of e
log.error( 'query threw Exception in QP.parse()', e )
}
return false
}
...但这有两个问题:首先,预期的 Exception
并不总是由测试代码而非应用程序代码创建的情况,其次,它在实际应用程序代码中检查识别测试行为的条件是错误的。
有"best practice"解决这个问题的方法吗?
如果只从一行中删除堆栈跟踪就可以了,您可以在记录器的模式布局中配置异常转换逻辑。下面是一个使用 log4j2 的例子:
public class ExceptionOutput {
private static final Logger LOG = LoggerFactory.getLogger(ExceptionOutput.class);
public static void main(String[] args) {
LOG.info("Foo", new NullPointerException("MESSAGE"));
}
}
log4j2 配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
alwaysWriteExceptions="false"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
注意 alwaysWriteExceptions=false
。它完全禁用异常输出。现在如果我们 运行 我们将得到的代码:
01:04:50.151 [main] INFO ExceptionOutput - Foo
但是如果你恢复到 alwaysWriteExceptions=true
,这也是省略参数时的默认行为,那么你会得到:
01:07:03.018 [main] INFO ExceptionOutput - Foo
java.lang.NullPointerException: MESSAGE
at ExceptionOutput.main(ExceptionOutput.java:8)
但还有更多。为了获得更大的灵活性,您可以在模式中使用 %throwable{...}
转换词,如 here in the Patterns table for the respective conversion pattern. In order to apply the logic only to tests you can have log4j2-test.xml on your classpath as explained here. Similar functionality of exceptions conversion also exists for other logging libraries, e.g. logback