【问题标题】:Unit testing: how to access a text file?单元测试:如何访问文本文件?
【发布时间】:2009-11-26 18:05:24
【问题描述】:

我正在使用带有 Microsoft 测试工具的 Visual Studio 2008。我需要从单元测试中访问一个文本文件。

我已经将构建操作设置为“内容”并复制到输出目录的文件配置为“始终复制”,但文件没有被复制到输出目录,根据System.Environment.CurrentDirectory

'{project_path}\TestResults\Pablo_COMPU 2009-11-26 15_01_23\Out'

这个文件夹包含了项目的所有DLL依赖,但是我的文本文件没有。

从单元测试中访问文本文件的正确方法是什么?

【问题讨论】:

    标签: visual-studio visual-studio-2008 unit-testing


    【解决方案1】:

    您必须将DeploymentItem 属性添加到您的测试类。使用此属性,您可以指定复制到 out 目录中以进行测试运行的文件。

    例如:

    [TestMethod]
    [DeploymentItem(@"myfile.txt", "optionalOutFolder")]
    public void MyTest()
    {
        ...
    }
    

    另请参阅:http://msdn.microsoft.com/en-us/library/ms182475.aspx

    【讨论】:

    • 这不适用于 NUnit。在这种情况下,请使用 Gavin 的方法。
    【解决方案2】:

    或者,如果您将所有文本文件设置为“复制到构建目录”,那么您可以通过这样做在测试中引用它们的路径

    var directory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
    var path = System.IO.Path.Combine(directory, "myFile.txt");
    

    【讨论】:

    • .. 从非托管代码调用时,GetExecutingAssembly 除外,例如Resharper 2016.2 测试运行器。
    • 最好使用System.IO.Path.Combine() 而不是那个字符串连接。否则,这适用于单元测试场景。
    • 我不认为这适用于 [TestMethod],它会抛出异常,因为您使用的是二进制测试工具(从非托管代码调用时它可以返回 null)所以您会得到一个异常.
    • 我同意 Micah 的观点,并对源代码进行了修改。
    【解决方案3】:

    当我需要一大段文本作为单元测试的一部分并且超过一两行时,我使用embedded resource。它不会弄乱您的测试代码,因为它是源代码中的一个单独的文本文件。它会直接编译到程序集中,因此您不必担心在编译后复制一个单独的文件。您的被测对象可以接受 TextReader,并且您传入通过加载嵌入资源获得的 StreamReader。

    【讨论】:

    【解决方案4】:

    由于我不使用 MSTest,因此无法回答您的问题。但是,我会考虑在单元测试中访问文件系统是否是正确的做法。如果你引入了对文件系统的依赖,测试会变得更慢,更不可信(你现在依赖的东西可能不存在/可访问/等)。正是由于这些原因,很多人会说“如果碰到文件系统就不是单元测试”。

    虽然这不是硬性规定,但始终值得考虑。任何时候我必须在测试中接触文件系统时,我都会尽量避免它,因为我发现依赖文件的测试更难维护,而且通常不太一致。

    我会在某种程度上考虑abstracting the file operations。你可以在这里做很多事情,从改变内部加载策略(通过依赖注入)到 - 甚至更好 - 分离文件的加载/使用,以便文件内容的使用者 甚至不必关心加载策略。

    【讨论】:

    • +1 Streams 或 TextReader/TextWriter 通常是足够的抽象。
    • 不确定您从哪里得到使用文件进行测试不好的想法。它不是。从文本文件中读取快速字符串并不是一项缓慢的操作,并且在测试(同一目录)中包含测试文件的一部分并不可信。
    • 我从一个项目中得到了这个想法,该项目由不同的人维护了 10k 个测试。那些接触文件的测试比不接触文件系统的测试更易变、更难维护和运行更慢。示例:我们不得不在重构会话期间找人来修复他们的测试,因为尽管文件存在并复制到输出目录,但我们得到了文件未找到错误。事实证明,这是一个依赖于顺序的测试中相当模糊的错误。内存单元测试根本不会发生这种情况。
    • 顺便说一句,我不是说“从不”这样做,我只是说如果可以避免它而不会造成太多麻烦,那就避免它!
    • 我的场景涉及测试使用 XML 的反序列化器。我想测试反序列化器,而不是 XML。所以在我的例子中,XML 作为一个文件是完全合法的。
    【解决方案5】:

    您是如何进行测试的?

    我们使用(TestDriven.net -> 运行测试)。

    根据我的经验,一些测试运行程序(例如 Netbeans 中的 Junit)不会自动复制您可能需要进行测试的任何其他文本文件。因此,在您的情况下,您可能必须进行完整构建,然后再次尝试运行测试。

    从测试中访问文本文件的正确方法是您尝试这样做的方式。 (将文件设置为“始终复制”和“内容”,并从编译目录访问它们)。

    另外,不确定人们从哪里得到的想法是让测试依赖文件是一件坏事。不是。

    如果有的话,拥有单独的测试文件只会清理您的测试并使它们更具可读性。考虑一些返回大字符串的 xml 解析方法:

    String expectedOutput = fileOperator.ReadStringFromFile("expectedFileContents.xml");
    String result = systemUnderTest.Parse(somethingtoparse);
    Assert.Equals(expectedOutput, result);
    

    想象一下,如果输出有 30 行长,你会用一个巨大的字符串弄乱你的测试代码吗?或者只是从文件中读取它。

    【讨论】:

    • 这是一个 Visual Studio 测试项目。测试 -> 运行 -> 解决方案中的所有测试。
    • 重建解决方案是否解决了问题?
    猜你喜欢
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    • 1970-01-01
    相关资源
    最近更新 更多