【发布时间】:2012-07-20 18:40:28
【问题描述】:
默认情况下,所有Logger 输出,在应用程序运行时可见,在应用程序测试时为静音。
如何强制调试、信息等显示在specs2 报告中?
【问题讨论】:
标签: scala playframework playframework-2.0 specs2
默认情况下,所有Logger 输出,在应用程序运行时可见,在应用程序测试时为静音。
如何强制调试、信息等显示在specs2 报告中?
【问题讨论】:
标签: scala playframework playframework-2.0 specs2
首先,您可能喜欢一些背景知识,为什么在测试模式下禁用日志记录。这是 Guillame Bort 在游戏论坛中对一个问题的回答(见 this thread):
记录器暂时在测试模式下被禁用,因为它会导致 运行测试时出现巨大的 PermGen 空间泄漏。但我们正在努力运行 在分叉的 JVM 中进行测试,因此我们将很快再次启用它。
作为一种解决方法,我创建了自己的记录器,如下所示(Scala 代码):
import play.api.{Play, LoggerLike, Logger}
import org.slf4j.LoggerFactory
import org.slf4j.impl.SimpleLoggerFactory
object MyLogger extends LoggerLike {
val factory = if (Play.isTest(Play.current)) {
new SimpleLoggerFactory()
} else {
LoggerFactory.getILoggerFactory
}
val redirectDebugToInfo = factory.isInstanceOf[SimpleLoggerFactory]
val logger = factory.getLogger("application")
def apply(name: String): Logger = new Logger(factory.getLogger(name))
def apply[T](clazz: Class[T]): Logger = new Logger(factory.getLogger(clazz.getCanonicalName))
// this method is to make debug statements to show up in test mode
override def debug(m: => String) = {
if (redirectDebugToInfo) {
info(m)
} else {
super.debug(m)
}
}
}
我不知道这段代码对于 PermGen 泄漏的一般表现如何,但到目前为止我还没有遇到这个问题。 要使其工作,您需要添加此依赖项:
"org.slf4j" % "slf4j-simple" % "1.6.4"
【讨论】:
SLF4J: Class path contains multiple SLF4J bindings. 警告?
如果您查看 Play Logger source,您会看到在测试模式下日志记录被禁用。
如果你真的想要记录,你可以创建记录配置文件进行测试,并将其作为系统属性“logger.file”传递给 Play。
示例日志记录配置(项目根目录中的 test-logger.xml 文件):
<configuration>
<conversionRule conversionWord="coloredLevel" converterClass="play.api.Logger$ColoredLevel" />
<logger name="application" level="INFO">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%coloredLevel %logger{15} - %message%n%xException{5}</pattern>
</encoder>
</appender>
</logger>
</configuration>
运行测试:
JAVA_OPTS="-Dlogger.file=test-logger.xml" play test
【讨论】:
我在conf下创建了一个logger.xml文件,如下:
<configuration>
<conversionRule conversionWord="coloredLevel" converterClass="play.api.Logger$ColoredLevel" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder><pattern>%coloredLevel %logger{15} - %message%n%xException{5}</pattern></encoder>
</appender>
<logger name="play" level="ERROR" />
<logger name="application" level="INFO" />
<root level="ERROR">
<appender-ref ref="STDOUT" />
</root>
</configuration>
然后我使用以下命令启动我的游戏环境:
播放-Dlogger.file=conf/logger.xml
瞧!在测试中记录数据。它确实会导致内存泄漏,但在开发过程中非常宝贵。
【讨论】:
如果你使用的是 FakeApplication,你可以传递一些配置信息:
FakeApplication(additionalConfiguration = Map(
"logger.application" -> "DEBUG"
))
这将 LOGGER 输出限制为调试和更高的输出。
我惊讶地发现设置是“粘性的”。如果早期测试使用 FakeApplication,那么以后不使用 FakeApplication 的测试仍将使用相同的日志记录级别。
【讨论】:
如果你使用 sbt 来运行测试(play 默认是这样),你可以在 Test 任务中设置 javaOptions 来控制使用的日志配置。
例如,在 project/Build.scala 中:
javaOptions in Test += "-Dlogger.file=conf/test-logger.xml"
更多关于 test-logger.xml 文件的语法在这里:
【讨论】:
testOptions in Test += Tests.Argument("-Dlogger.file=conf/test-logger.xml") 配置日志记录,但单元测试根本没有日志记录。
play.Project,这可以正常工作。感谢@jamesinchina 的更新
Test / javaOptions += "-Dlogger.file=conf/test-logger.xml"