【问题标题】:How do I assign JUnit output to a String?如何将 JUnit 输出分配给字符串?
【发布时间】:2014-05-06 04:37:53
【问题描述】:

我想在单元测试失败时在我的问题跟踪软件中创建错误报告。这意味着当测试失败时,我需要将通常打印到 IDE 控制台的内容保存为字符串。到目前为止,我有以下代码:

@Rule
public ErrorCollector collector = new ErrorCollector();
...

@Test
public void testFailedUnitTest() {
    collector.checkThat(3, equalTo(5));
}

它将以下内容输出到控制台。除了将其输出到我的 IDE 控制台之外,我还想将其放入字符串中:

java.lang.AssertionError: 
Expected: <5>
     but: was <3>
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
    at org.junit.Assert.assertThat(Assert.java:865)
    ...

我试过了:

  1. 用 try/catch 块包围它并使用 e.get... 但是 它没有捕获 java.lang.AssertionError。 catch 块中的代码甚至没有被执行。我认为那是因为 我的收集器正在等待之后抛出异常 testFailedUnitTest() 完成 抛出错误,以便它可以 继续执行失败的测试。

  2. 使用 try/catch 块围绕正常的非收集器 JUnit 测试。

  3. 在我的 tearDown() 中获取输出,在所有测试完成之后 完全的。但是没有像 public String[] 这样的方法 the ErrorCollector JavaDoc 中的 getJUnitFailures() 所以 那没用。

  4. 在我的 pom.xml 中编辑某些内容的各种方法,例如 setting the redirectTestOutputToFile element to true,但它们与 2) 存在相同的问题,不幸的是,一些遗留代码不使用 Maven。但是,可以接受特定于 Maven 的方法。

我亲自与某人交谈,他说我可能能够使用the Logger class 将每个测试的输出记录到文件中,并将每个文件作为字符串读取。他承认这是一种草率的黑客行为,可能会干扰我们的其他日志记录设施。

这是否可行,如果可行,这是最好的方法吗?

提前谢谢你。 :)

【问题讨论】:

  • 我也在使用 JUnit 4.11,但如果解决方案是特定于版本的,我可以轻松更改 pom.xml 中的版本。
  • 你的要求很奇怪。最好的选择是将所有控制台输出重定向到日志文件。您可以为此使用 log4j,并且您应该能够获取从您的 junit 记录的正确日志数据,因为其他日志也将在那里。为此,您应该使用可以搜索的字符串修改 log4j.properties 文件中的 appender。
  • 这可能行不通。您在这里有点重新创建轮子 - 我建议您使用生成文档的现有测试框架,也许是声纳?
  • @EvanKnowles 您的评论超出了我的问题范围。我正在尝试将失败的 JUnit 堆栈跟踪分配给字符串,以便我可以在 Jira 中自动创建问题,而不是自动生成文档。
  • 啊,我明白了。我觉得使用 Sonar 等工具会更容易,然后使用它生成的 XML 作为结果的一部分来创建 Jira 问题。

标签: java maven logging junit java-6


【解决方案1】:

看起来TestWatcher 可以为所欲为。


示例

import java.io.PrintWriter;
import java.io.StringWriter;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;

public class FailedTestCapturer {

  @SuppressWarnings("null")
  private static int throwNPE() {
    String x = null;
    return x.length();
  }

  private String exception;
  @Rule
  public final TestRule watchman = new TestWatcher() {
    @Override
    protected void failed(Throwable e, Description description) {
      StringWriter writer = new StringWriter();
      e.printStackTrace(new PrintWriter(writer));
      exception = writer.toString();
      System.out.println("Captured exception! --> " + exception);
    }
  };

  @Test
  public void failingTest() {
    throwNPE();
  }
}

输出

Captured exception! --> java.lang.NullPointerException
    at FailedTestCapturer.throwNPE(FailedTestCapturer.java:15)
    at FailedTestCapturer.failingTest(FailedTestCapturer.java:32)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

【讨论】:

    猜你喜欢
    • 2019-05-18
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 2015-02-08
    • 2015-05-04
    • 2016-04-08
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多