Logging in Unit Tests, a Bad Practice

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

日志记录是调试的必然部分。至少在现代高级编程语言和架构中是如此。三十年前的汇编语言并不需要日志记录,但现在需要了。有时我们会追踪变量,但很少这样做。更常见的是将它们打印到控制台。此外,我们不仅仅使用println或其他用于控制台打印的方法,而是发送消息给一个日志记录框架,该框架处理控制台或其他日志记录目标,比如文件。这样的框架之美在于,我们无需在调试结束后删除日志记录,只需配置框架以在生产环境中抑制所有调试级别的消息。在单元测试中可能会发生一些日志记录。我们也应该将它们留在那里吗,或者不应该?

这里有一个例子(它是我们目前正在开发的静态分析器Polystat中的一个真实单元测试CalcTest.java的简化版本):

这是Java,我正在使用JUnit5+Hamcrest以及我自己的日志框架jcabi-log,它是Slf4j的装饰器,使用Log4j打印到控制台。

这里发生了什么?有一个名为Foo的类,其中有一个名为build()的方法,它生成一个XML文档(我正在使用jcabi-xml库,它是JDK DOM的装饰器)。然后,单元测试将XML文档的内容打印到控制台,并进行了一个非常简单的断言:文档不是NULL。这个断言很简单,因为如果它是NULL,那么日志语句在.toString()调用时就会失败。

我是这段代码的开发者,所以我知道发生了什么:我懒得编写一个适当的断言,它可以查看XML文档并确保其中有正确的元素。我只是将它打印到控制台上,目视确认其有效性,然后就这样了。如果我有更多时间,我会编写一个更好的单元测试(我刚刚在Polystat测试中进行了改进):

现在,XML文档已经构建并测试是否存在//foo XPath。只有在断言失败的情况下,文档的内容才会被打印到控制台上。如果XML具有所需的XPath,就不会有控制台输出,这意味着对未来开发人员来说没有噪音。

此外,现在这是一个单语句测试,本身就是一个好的实践。

回顾我在测试和日志记录方面的经验,我认为在单元测试中记录日志是一个不好的主意。有时候不可避免,因为我们懒惰或者只是没有足够的时间,但仍然是不好的。日志记录帮助我们通过视觉确认输出的正确性,但它却带走了项目的这种知识。以后将与测试一起工作的人将不知道我们在那里看到了什么。他们将在控制台上看到输出,但无法理解它是否仍然符合我在编写时的期望。

我想说,在单元测试中的每一行日志记录都是作者的一个信息:“我对我现在看到的数据有一些了解,但我懒得告诉你,你只需要相信它看起来很好。”

我建议我们不要在我们的代码中留下这样的信息。

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-12-15 at 06:47

sixnines availability badge   GitHub stars