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

Unit testing 单元测试中的文件访问是否不好?,unit-testing,Unit Testing,在编写处理XML的单元测试(例如,测试读取/生成XML的类)时,我通常在单元测试旁边的单独文件中编写断言的结果XML字符串/输入XML字符串。假设我有一个类“MyTransformer”,它将一种XML格式转换为另一种XML格式。然后我将在同一个包中创建三个文件: MyTransformerTest.java MyTransformerTestSampleInput.xml MyTransformerTestExpectedOutput.xml 那么我的断言可能如下所示(为了简单起见,简化了

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

  • MyTransformerTest.java
  • MyTransformerTestSampleInput.xml
  • MyTransformerTestExpectedOutput.xml
那么我的断言可能如下所示(为了简单起见,简化了伪代码):

Reader transformed=MyTransformer.transform(getResourceAsStream(“MyTransformerTestSampleInput.xml”);
Reader expected=getResourceAsStream(“MyTransformerTestExpectedOutput.xml”);
assertXMLEqual(预期、转换);
然而,一位同事告诉我,我在这个单元测试中拥有的文件访问权限是不可接受的。他建议创建一个包含XML文件内容的文本字符串常量(private static final string),可能是在一个单独的groovy类中,因为多行字符串的好处是,而不是将XML文件写入文件中

我不喜欢文字字符串常量的概念,因为即使我在groovy中有多行字符串,我仍然会丢失语法突出显示和XML编辑器的所有其他有用功能,这些功能会立即告诉我XML是否有语法错误等


你觉得怎么样?文件访问真的很糟糕吗?如果是:为什么?如果没有,为什么可以?

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

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

也就是说,我不会对测试中不使用文件太严格。如果可能的话,尽量避免他们,但不要生气。确保你考虑维修性与速度-更干净的测试,更容易修复和理解它。p> 如果您的单元测试访问这些文件,将虚假的测试数据提供给被测系统,这样您就可以运行测试,这不是问题。这实际上有助于您在被测系统中使用更广泛的测试数据

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


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

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

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


因此,这完全取决于单元/集成测试定义。这两种测试都是有效的,这取决于您当时编写的测试。

如果xml更可读,或者更易于在文件中使用,并且您有很多这样的测试,我将不使用它们

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

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

如果您在Windows和LINUX中工作,则必须小心生成服务器拾取文件


没有完美的答案。

你可以在一个test/resources文件夹中保存所有这些内容。如果您有某种XML模板,可以在其中进行参数化,那就更好了。小XML字符串或使用groove表示字符串不是个好主意(在我看来…),可能mock会有所帮助,这取决于