在单元测试中是否有任何简单的slf4j用法模式?

yeg*_*256 16 java slf4j

我在我的项目中使用JUnit4和Hibernate3.Hibernate依赖于Slf4j,因此我的项目也包含了这个库.现在我想在单元测试中使用Slf4j来记录补充测试信息.您能否提供一个简短的示例,说明我的单元测试应该如何只记录一行文本?优选地,在多个测试中没有代码重复.

dty*_*dty 13

为什么要在单元测试中记录内容?单元测试应该通过/失败,并应使用测试框架来表明.您不希望通过输出读取以查看测试是通过还是失败.如果它失败了,在IDE /调试器中运行它是修复它的最佳方法.

  • 因为有时候知道测试失败的原因是有用的,或者可能打印性能指标,以防你想要随便关注这些. (14认同)
  • @dty在您创建测试时,测试期间的日志记录非常重要.测试完成后,日志消息已过时,但它们不会伤害任何人.当测试再次失败时,例如,在1年内,您将有兴趣回到它们.当然,在一个理想的世界中,只有断言就足够了.但是我们经常需要日志记录. (8认同)
  • 在我所有的(可观的!)年里,我从未觉得需要将记录添加到单元测试中.对我来说,这种单元测试的气味太复杂了.但无论如何,我不确定你的问题与"我如何使用slf4j"有何不同.我不确定如何在单元测试中使用它与问题相关.从单元测试中使用它与从生产代码中使用它有什么不同? (8认同)
  • 如果您想进行性能测试,请正确执行并捕获并绘制数字图表.从UT运行中随意观察一些数字并不是衡量绩效的方法.至于测试失败的原因,您应该编写断言,以便文本告诉您出了什么问题.在工作中,我们的产品有数万个单元测试; 如果我们必须从那些读取输出,你认为我们会在哪里? (6认同)
  • 对不起,我只是不明白.您是否对表现感兴趣.如果是的话,在日志文件中间发现一些数字并不是跟踪正在发生的事情的方法.至于其他"有价值"的日志记录,被测系统也可能正在进行自己的日志记录,因此在任何其他日志记录中查看测试所做的日志记录必须是棘手的.我回到我原来的说法 - 单元测试应该是红色/绿色,通过/失败.如果测试失败,失败消息应告诉您原因. (5认同)
  • 我没有说性能测试,我只是随便跟踪它作为你可能想要登录测试的一个例子.至于你的工作,是的,我们也有成千上万的测试,你会惊讶地发现你想要的特定测试信息的速度有多快.此外,你不需要阅读它们,除非你真的需要,当你真的需要的时候,该死的方便已经有了原木. (2认同)

Jim*_*ugh 11

我也喜欢在我的DAO类的JUnit测试中使用slf4j.当您创建新测试或修改旧测试时,它会有所帮助.我通常将我的旧日志输出保留在调试级别,并在信息级别创建新的日志记录语句,而我仍在积极处理该方法中的代码.我的一个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");
    }

}
Run Code Online (Sandbox Code Playgroud)

我使用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>
Run Code Online (Sandbox Code Playgroud)

这给了我来自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时所做的.如果使用其他日志记录实现,则相应地进行调整.如果您使用不同版本的slf4j并不重要,只要"API"和实现JAR是相同的版本(我的是1.6.0).


Ed *_*fin 5

另一种解决方案是将日志记录实现切换为仅用于测试的简单实现.

所以在你的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>
Run Code Online (Sandbox Code Playgroud)

SimpleLogger默认情况下只将所有内容记录到stderr,不需要任何配置文件

  • SimpleLogger 默认日志级别是 INFO。例如,要将其更改为 DEBUG,请使用 JVM 选项 -Dorg.slf4j.simpleLogger.defaultLogLevel=DEBUG (2认同)