【问题标题】:How to read console output in maven surefire unit test如何在 Maven Surefire 单元测试中读取控制台输出
【发布时间】:2019-04-02 04:33:17
【问题描述】:

我正在尝试测试一个必须将特定字符串打印到 System.out 的方法。

我已经使用this answer 让这个与 JUnit 一起工作。

这适用于 JUnit,但测试随后在 CI 环境中由 Maven surefire 运行。然后测试失败,可能是因为 Maven 捕获了 System.out 并且它对测试不可用?

有人可以帮我找到在此 Surefire 测试中使用控制台输出的方法吗?

这是我的测试:

private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
private final PrintStream originalOut = System.out;
private final PrintStream originalErr = System.err;

@Before
public void setUpStreams() {
    System.setOut(new PrintStream(outContent));
    System.setErr(new PrintStream(errContent));
}

@After
public void restoreStreams() {
    System.setOut(originalOut);
    System.setErr(originalErr);
}



@Test
public void testUpdateData() throws Exception {
    MyData data = new MyData();
    DataUtil.updateData(data);
    Assert.assertTrue(outContent.toString().contains("is updating data within last 24h")); // assert that warning issued
}

测试类:

public final class DataUtil {
    public static void updateData(Data d) {
        /// do stuff
        if (/*condition*/) {
            System.out.println("data " + d.id +  "is updating data within last 24h");
        }
    }
}

Maven 测试的输出:

testUpdateData  Time elapsed: 0.035 sec  <<< FAILURE!
java.lang.AssertionError: null
    at org.junit.Assert.fail(Assert.java:86)
    at org.junit.Assert.assertTrue(Assert.java:41)
    at org.junit.Assert.assertTrue(Assert.java:52)

【问题讨论】:

  • 我已经尝试过使用 maven 的 -Dsurefire.useFile optin,但它对测试结果没有影响
  • 正如您所发现的,对该问题的高度投票答案实际上是错误的方法。正确答案其实是*.com/a/21216342/545127
  • Raedwald 谢谢,但我更喜欢不需要更改 DataUtil 类(如果有的话)的解决方案,因为我希望在整个项目中与输出写入保持一致,并希望避免重构过多。

标签: java maven junit maven-surefire-plugin system.out


【解决方案1】:

我通过将 System.out.println() 更改为使用 log4j 记录来解决此问题。

Raedwalds comment and link7 之后,我决定丢弃旧的系统输出。但我没有使用 PrintStreams,而是更进一步,重构了代码以使用 Log4j 日志记录。

然后我使用this answer 从单元测试中读取输出的日志。

【讨论】: