在单元测试中是否有任何slf4j用法的简单模式?
我在我的项目中使用JUnit4和Hibernate3。 Hibernate依赖于Slf4j,因此我的项目也包含这个库。现在我想在单元测试中使用Slf4j以记录补充测试信息。您能否提供一个简单的示例,说明我的单元测试应该如何才能记录一行文本?在多次测试中,最好是没有代码重复。在单元测试中是否有任何slf4j用法的简单模式?
我也喜欢用SLF4J在我的JUnit测试我DAO类。它在您创建新测试或修改旧测试时确实有帮助。我通常会将我的旧日志记录输出保留在调试级别,并在信息级别创建新的日志记录语句,同时我仍在积极研究该方法中的代码。我的一个JUnit类的会是这个样子:
package com.example.mydao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// other imports not shown...
public class TestMyDAO extends TestCase {
private static final Logger logger =
LoggerFactory.getLogger(TestMyDAO.class);
public void testA() {
logger.debug("Logging from testA() method");
}
public void testB() {
logger.debug("Logging from testB() method");
}
public void testThatIAmWorkingOn() {
logger.info("Logging from my new test method at INFO level");
}
}
我使用log4j的是实际的记录供应商,所以我log4j.xml
配置文件看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
<appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c{1}] %m %n" />
</layout>
</appender>
<logger name="com.example.mydao" additivity="false">
<level value="INFO" />
<appender-ref ref="consoleAppender"/>
</logger>
<logger name="org.hibernate" additivity="false">
<level value="WARN" />
<appender-ref ref="consoleAppender"/>
</logger>
<logger name="org.hibernate.connection.DriverManagerConnectionProvider" additivity="false">
<level value="INFO" />
<appender-ref ref="consoleAppender"/>
</logger>
<logger name="org.hibernate.connection.C3P0ConnectionProvider" additivity="false">
<level value="INFO" />
<appender-ref ref="consoleAppender"/>
</logger>
<logger name="com.mchange" additivity="false">
<level value="WARN" />
<appender-ref ref="consoleAppender"/>
</logger>
<logger name="com.mchange.v2.resourcepool.BasicResourcePool" additivity="false">
<level value="INFO" />
<appender-ref ref="consoleAppender"/>
</logger>
<logger name="com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource" additivity="false">
<level value="INFO" />
<appender-ref ref="consoleAppender"/>
</logger>
<logger name="com.mchange.v2.c3p0.C3P0Registry" additivity="false">
<level value="INFO" />
<appender-ref ref="consoleAppender"/>
</logger>
<root>
<priority value ="WARN" />
<appender-ref ref="consoleAppender"/>
</root>
</log4j:configuration>
这给了我的信息从我的JUnit类输出,以及Hibernate运行时和Hibernate使用的其他库中的一些有用的东西。根据自己的口味调整。
最后,我需要确保所有的下列库都在我的类路径中,当我执行JUnit测试:
slf4j-api-1.6.0.jar
slf4j-log4j12-1.6.0.jar
log4j-1.2.16.jar
-
log4j.xml
(我的配置文件,如上所示) - 某些版本的JUnit运行时JAR
- 在生产中运行应用程序时,通常存在的所有JAR
这就是我在使用log4j时所做的。如果您使用不同的日志记录实施,则相应地进行调整。只要“API”和实现JAR是相同版本(我的版本都是1.6.0),使用不同版本的slf4j并不重要。
为什么你想在单元测试中记录东西?单元测试应该是合格/不合格,并且应该使用测试框架来表明这一点。您不想通过输出来阅读测试是否通过或失败。如果它失败了,那么在IDE /调试器中运行它是修复它的最好方法。
因为它有时可以用来了解测试失败的原因,或者打印性能指标,以防您随意关注这些测试。 – BjornS 2010-09-29 11:43:50
如果您想进行性能测试,请正确执行并捕获并绘制数字。随便看看UT跑步中的一些数字并不是衡量表现的方法。至于为什么一个测试失败,你应该写你的断言,所以文本告诉你出了什么问题。在工作中,我们的产品有数万个单元测试;如果我们必须阅读那些输出结果,你认为我们会在哪里? – dty 2010-09-29 11:47:13
我没有说性能测试,我只是说随便跟踪它作为你为什么要登录你的测试的例子。至于你的工作,是的,我们也有数以万计的测试,你会惊讶地发现你想要的信息与特定测试有关。此外,除非你真的需要,而且当你真的需要的时候,你不需要阅读它们,它的方便已经有日志了。 – BjornS 2010-09-29 11:52:52
这对我来说似乎是一种难闻的气味。
您应该始终避免手动检查或单元测试验证。
单元测试应该是自动化的,如果你的构建工具告诉你,某些测试失败应该只需要人工干预,并应使用所有这些验证方法(如的assertEquals)
当然可以。 OP想知道代码*应该看起来像做什么,我们中的许多人都建议不要存在代码。这就是它*应该如何。 – iX3 2015-02-03 14:45:16
有趣的是,dyt的另一个答案基本上是说类似的东西(人们应该避免因为blablabla而在单元测试中登录)。我的回答是收到更多的赞誉。 LOL – 2015-11-24 07:00:51
在测试期间记录通常是非常宝贵的,特别是当测试失败时。当测试通过或日志变得不可读时,这当然需要与过多的日志记录进行平衡。 – AntonPiatek 2017-12-14 15:51:40
我们使用log4j的提供失败的原因作为我们的输出记录器;
private static Logger log = LoggerFactory.getLogger(MyClassHere.class);
如果您正确配置它,slf4j应找到并使用log4j而不会出现问题。 为了让生活方便,我会用这个Eclipse的模式,因为您将编写这些代码公平一点:
private static Logger log = LoggerFactory.getLogger(${enclosing_type}.class);
${:import(org.slf4j.Logger,org.slf4j.LoggerFactory)}
的测试中,我建议你不要超越INFO水平,并保持最事情DEBUG 。如果你真的想要智能地捕捉很多错误,那么我建议你查看一下PositronLogger,它是一个日志文件appender,它会静静地将所有东西都提取到TRACE中,但只有在捕获错误时才将其转储到文件;有点像时间旅行:)
我需要在'@ Before'注释的方法内的每个单元测试中执行'getLogger()',对吧? – yegor256 2010-09-29 14:12:49
不,只是私有静态引用,那么你可以简单地调用log.debug(“some stuff”);无论你喜欢哪里。编辑:我应该澄清; LoggerFactory.getLogger()是静态引用的一部分,您不需要在@Before中调用它,只需将其作为测试类中的字段输入即可。一个简单的例子:class MyTests {private static Logger log = LoggerFactory.getLogger(MyTests.class); @Test public void magic(){log.info(“...”); }} – BjornS 2010-10-01 08:26:45
Slf4j是一个日志门面,您可以在运行时决定实现。 Slf4j只是一个API。例如,你可以使用log4j作为底层实现。你需要在你的pom.xml中包含两个依赖。
<!-- Depend on slf4j API -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<!-- Use log4j as the slf4j implementation -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
的事情是,运行在IDE或通过mvn test
单元测试时,它可以是恼人设置log4j的配置。尤其是以一种不需要做任何事情的方式工作。除非在类路径上有一个log4j.properties
文件或者设置了-Dlog4j.configuration=file:///path/to/log4j.properties
,否则Log4j默认拒绝记录任何内容。
一种解决方案是把在单元测试,代码设置log4j的配置编程:
@BeforeClass
public static void beforeClass() {
BasicConfigurator.resetConfiguration();
BasicConfigurator.configure();
}
这只是工作,但它需要在每单元测试这是一种痛苦被投入。 。
另一种解决方案是将日志记录实现切换为仅用于测试的简单实现。
所以在你的pom.xml
<!-- Depend on slf4j API -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<!-- Use SimpleLogger as the slf4j implementation in test -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.12</version>
<scope>test</scope>
</dependency>
<!-- Use log4j as the slf4j implementation during runtime (not test) -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
<scope>runtime</scope>
</dependency>
的SimpleLogger只是默认记录一切标准错误,并且不需要任何配置文件
SimpleLogger默认日志级别是INFO。例如,要将其更改为DEBUG,请使用JVM选项 -Dorg.slf4j.simpleLogger.defaultLogLevel = DEBUG – 2017-10-25 15:31:54
添加日志记录在写新的测试是非常有用的。与此同时,当测试在CI或CD管道中运行时,您希望禁用日志记录(或者至少不要冗长)。有时候故障是暂时的,特别是在端到端的运行中,所以在CI作业的控制台日志上输出相关的输出是有帮助的。这篇文章很好地描述了它 - https://gualtierotesta.wordpress.com/2015/11/01/tutorial-logging-during-tests/
为避免代码重复,您可以将导入和“Logger”声明移至抽象的“TestCase”子类。 – 2012-11-12 21:34:46