【问题标题】:Log4J with JUnit Tests带有 JUnit 测试的 Log4J
【发布时间】:2015-07-21 02:03:38
【问题描述】:

我想在我的 Selenium Java 测试中添加日志记录。我已经实现了 log4jFramework,它可以很好地将日志放在控制台或文件中。

我正在使用 JUnit 测试框架,我想在日志文件的文件名中包含测试名称和日期/时间,而不是使用似乎是在文件前面加上数字 +1 的标准约定文件已存在。

这是我的 log4j.properties 文件...

log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.File=~/Desktop/Selenium/AutomationLogs/automationLog
log4j.appender.rollingFile.MaxFileSize=2MB
log4j.appender.rollingFile.MaxBackupIndex=2
log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss} %p %t %c - %m%n

我在网上找到的似乎只与每日滚动文件有关。我想在每次运行单元测试时为日志生成一个新文件

【问题讨论】:

标签: java selenium junit log4j


【解决方案1】:

如果我正确理解您的需求,这可以通过结合以下方式来实现:

  • 使用 JUnit 方法规则,该规则将为您提供当前方法的名称
  • 在运行时创建一个Log4j appender,并用你刚刚获得的方法名进行配置

具体来说,您需要创建一个自定义 JUnit 规则。我选择扩展TestWatcher,因为它似乎最合适

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.RollingFileAppender;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;

public class TestMethodLogging extends TestWatcher {
  private static final String date = new SimpleDateFormat("y-MM-dd")
      .format(new Date());
  private Logger logger;

  @Override
  protected void starting(Description description) {
    String name = description.getMethodName();
    RollingFileAppender a = (RollingFileAppender) Logger.getRootLogger()
        .getAppender("rollingFile");
    PatternLayout layout = new PatternLayout();
    layout.setConversionPattern("%d{dd MMM yyyy HH:mm:ss} %p %t %c - %m%n");

    try {
      File logDir = new File(a.getFile()).getParentFile();
      File logFile = new File(logDir, name + "_" + date);
      logger = Logger.getLogger(name);
      logger.addAppender(new RollingFileAppender(layout, logFile
          .getAbsolutePath()));
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  public Logger getLogger() {
    return logger;
  }
}

一旦你有了这个,你就可以把它作为一个规则放在你的测试类中。规则只是测试中的一个字段(带有@Rule 注释)。在这里我称之为rule(我承认不是很有想象力)。为了从您的测试方法中登录,您需要调用rule.getLogger()。

import static org.junit.Assert.assertEquals;

import org.junit.Rule;
import org.junit.Test;

public class MyTest {
  @Rule
  public TestMethodLogging rule = new TestMethodLogging();

  @Test
  public void sumOfTwoInts() throws Throwable {
    rule.getLogger().error(
        "logging to a logger whose name is based on the test method's name");
    assertEquals(5, 2 + 3);
  }

  @Test
  public void productOfTwoInts() throws Throwable {
    rule.getLogger().error(
        "logging to a logger whose name is based on the test method's name");
    assertEquals(8, 2 * 4);
  }
}

当我运行这个测试时,它会在我的~/Desktop/Selenium/AutomationLogs 目录下创建这两个文件:

productOfTwoInts_2015-05-10  
sumOfTwoInts_2015-05-10

第一个文件的内容如下:

$ cat productOfTwoInts_2015-05-10 
10 May 2015 19:59:58 ERROR main productOfTwoInts - logging to a logger whose name is based on the test method's name
10 May 2015 20:01:22 ERROR main productOfTwoInts - logging to a logger whose name is based on the test method's name
10 May 2015 20:01:24 ERROR main productOfTwoInts - logging to a logger whose name is based on the test method's name

【讨论】:

  • 感谢一百万,这正是我所追求的
  • 不客气 :) 请注意,我只是稍微更改了 TestMethodLogging 类。具体来说,SimpleDateFormat 现在只使用一次,从而避免了它的线程安全问题 (stackoverflow.com/questions/6840803/…)
  • cc @DanielCohen -- 我还稍微改变了传递给 SimpleDateFormat 的模式:如果需要,日/月现在有一个前导零,以便我们得到 2015-05-10(而不是 2015- 5-10)
猜你喜欢
  • 2014-03-09
  • 2020-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-10
  • 1970-01-01
相关资源
最近更新 更多