我们应该测试控制台输出吗?

时间:2013-03-02 13:47:42

标签: java junit tdd legacy cobertura

我正在处理一些本身有一些System.out.print命令的遗留代码。 我的eCobertura插件显示这条线为红色,所以我想对它们进行单元测试。

stackoverflow中的

Here我发现了一种单元测试控制台输出的方法,我认为非常有趣。

我就是这样做的:

        private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();

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

        @After
        public void cleanUpStreams() {
            System.setOut(null);
        }

        @Test
        public void out() {
            System.out.print("Some message from the system");
            assertEquals("Some message from the system", outContent.toString());
        }

到目前为止,测试变得很好,但是当我再次运行代码覆盖率插件时,我收到此消息:

  

线程“Thread-0”中的异常java.lang.NullPointerException at   net.sourceforge.cobertura.coveragedata.TouchCollector.applyTouchesOnProjectData(TouchCollector.java:186)     在   net.sourceforge.cobertura.coveragedata.ProjectData.saveGlobalProjectData(ProjectData.java:267)     在   net.sourceforge.cobertura.coveragedata.SaveTimer.run(SaveTimer.java:31)     在java.lang.Thread.run(Thread.java:662)

我有些疑惑:

  • 尝试单元测试System.out.print()'s是否正确?
  • eCobertura是否与此类测试兼容?
  • 如果eCobertura与此类测试不兼容,为什么它会显示红线?
  • 我的测试中有什么问题吗?
  • 我正在使用jUnit 4.11你认为这与它有关吗?
  • 为什么eCobertura会给我这个错误?

2 个答案:

答案 0 :(得分:6)

尝试单元测试System.out.print()是否正确?

这在很大程度上取决于您要测试的内容。我不认为有必要测试System.out.print()本身,我希望Sun / Oracle已经做到了这一点。但是,如果您的应用程序向控制台输出重要信息,这是验证输出的唯一方法,那么您需要对其进行测试。 如果您可以通过测试相应的类来测试代码,那么您可能不需要测试输出流本身。

查看数据库,例如:我不是自己测试JDBC驱动程序,但我会测试所有代码/功能,这些代码/功能是从数据库加载/保存数据的一部分。

红线仅表示从未执行过代码行。这可能没问题,也可能意味着您的测试不会触及他们应该使用的部分代码。获得高测试覆盖率很重要,但可能并不总是需要100%的目标(想想帕累托原则)

关于你的空指针异常

您对System.setOut(null);的调用将System.out设置为null,eCobertura可能会尝试向Standard Out写入内容,现在为null。您可能需要在@Before方法中保存orignial Out Stream并在@After方法中恢复它以允许后面的代码使用StdOut

eCobertura与此类测试不兼容吗?

如果eCobertura与此类测试不兼容,为什么会显示红线?

为什么eCobertura会给我这个错误?

可能是eclipse和eCobertura之间的通信是通过Standard Out发生的,但我不确定。如果是这种情况,那么与重定向标准输出相比,不仅是您的输出,而且Cobertura的输出也会被重定向,并且GUI不再看到执行的内容和不执行的内容,因此将其着色为红色

我的测试中有什么问题吗?

可能需要确保正确恢复StdOut。

我正在使用jUnit 4.11您认为这与它有关吗?

不,我不这么认为

答案 1 :(得分:3)

如果在您的代码中使用System.out.println是正确的,那么(单元/集成)测试它们是正确的。

有一个名为System Rules的有用的系统测试实用程序,用于测试这种代码。

http://stefanbirkner.github.com/system-rules/