单元测试中的文件访问是不是不好?

Posted

技术标签:

【中文标题】单元测试中的文件访问是不是不好?【英文标题】:Is file access in unit tests bad?单元测试中的文件访问是否不好? 【发布时间】:2013-06-18 11:06:46 【问题描述】:

在编写处理 XML 的单元测试时(例如,测试一个读取/生成 XML 的类),我曾​​经将我的断言结果 XML-String /我的输入 XML 字符串写在我的单元测试旁边的单独文件中。假设我有一个类“MyTransformer”,它将一种 XML 格式转换为另一种。然后我会在同一个包中创建三个文件:

MyTransformerTest.java MyTransformerTestSampleInput.xml MyTransformerTestExpectedOutput.xml

那么我的断言可能看起来像这样(为简单起见,简化了伪代码):

Reader transformed = MyTransformer.transform(getResourceAsStream("MyTransformerTestSampleInput.xml")));
Reader expected = getResourceAsStream("MyTransformerTestExpectedOutput.xml");
assertXMLEqual(expected, transformed);

但是一位同事告诉我,我在此单元测试中拥有的文件访问权限是不可接受的。他建议创建一个包含我的 XML 文件内容的文字字符串常量(私有静态最终字符串),可能在一个单独的 groovy 类中,因为多行字符串的好处而不是将 XML 文件写入文件。

我不喜欢文字字符串常量的想法,因为即使我在 groovy 中有多行字符串,我仍然会松散语法高亮以及我的 XML 编辑器的所有其他有用功能,如果我的 XML 有语法错误,它们会立即告诉我等等

你怎么看?文件访问真的很糟糕吗?如果是这样:为什么?如果不是,为什么可以?

【问题讨论】:

你可以在 test/resources 文件夹中存放所有这些东西。如果您在其中有某种 XML 模板,您接下来可以对其进行参数化,那就更好了。小 XML 字符串或使用凹槽来表示字符串不是好主意(在我看来......)也许 mock 会有所帮助,这取决于 【参考方案1】:

单元测试中文件的两个问题:

它们会减慢测试周期。您可能有数千个单元测试,最好在每次构建时运行它们 - 所以它们应该尽可能快。如果您可以加快它们的速度(例如,通过摆脱 I/O 操作),您会想要这样做。当然这并不总是可行的,所以你通常通过NUnit [Category] 或类似的东西分离出“慢”测试——然后不那么频繁地运行这些特殊测试——比如,只在 Nightly 构建上运行。 它们引入了额外的依赖项。如果一个测试需要一个文件,它不仅会在测试背后的逻辑错误的情况下失败,而且会在文件丢失,或者测试运行程序没有读取权限等情况下失败。这使得调试和修复不那么令人愉快!

也就是说,我不会对在测试中不使用文件过于严格。如果可能的话,尽量避免他们,但不要生气。确保您考虑可维护性与速度 - 测试越干净,以后修复和理解它就越容易。

【讨论】:

【参考方案2】:

如果您的单元测试访问文件以将伪造的测试数据提供给被测系统,那么您就可以运行测试,这不是问题。这实际上有助于您在被测系统中使用更多种类的测试数据。

但是,如果您的被测系统访问文件系统,则在从测试执行时,这不是单元测试。那是一个集成测试。这是因为您正在访问诸如文件系统之类的横切关注点,它们不能归类为单元测试。

您将真正隔离/伪造文件访问并使用单元测试测试您的代码的行为(如果有的话)。它们运行起来更快、更容易。如果写得正确,它会给你一个精确的反馈。

【讨论】:

【参考方案3】:

在这些情况下,我有一个使用文件内部表示的单元测试,在这种情况下是字符串文字。

我还将进行集成测试,以测试代码在写入文件时是否正常工作。

所以这完全取决于单元/集成测试定义。两者都是有效的测试,只是取决于您当时正在编写的测试。

【讨论】:

【参考方案4】:

如果 xml 更具可读性,或者在文件中更易于使用,并且您有很多这样的测试,我会留下它们。

严格来说,单元测试不应该使用文件系统,因为它很慢。但是,可读性更重要。文件中的 XML 更易于阅读,并且可以在 XML 友好的编辑器中加载。

如果测试需要很长时间才能运行(因为您有很多测试),或者您的同事抱怨,请将它们移至集成测试。

如果您在 Windows 和 LINUX 中工作,则必须小心文件会被构建服务器拾取。

没有完美的答案。

【讨论】:

以上是关于单元测试中的文件访问是不是不好?的主要内容,如果未能解决你的问题,请参考以下文章

用于单元测试 Objective-C XCTest 的 .m 文件中的访问变量定义

grails Grails 单元测试中的应用程序访问

访问 OCUnit 测试目标中的 UIImage

没有发现 您访问的地址或文件/未定义在此服务器上没有被找到。 这是怎么回事

springboot系列SpringBoot 单元测试配置访问配置项目打包发布加载和读取多个配置文件

如何让单元测试访问核心数据模型