Visual Studio - 单元测试在项目中加载资源

时间:2009-10-08 23:27:57

标签: c# visual-studio unit-testing filepath

目标是在这些Xml文件中给出一些数据来运行一些测试。

如何在单元测试方法中轻松地将给定的Xml文件加载到XmlDoc中?

现状是:

  XmlDocument doc = new XmlDocument();
  string xmlFile = "4.xml";
  string dir = System.IO.Directory.GetCurrentDirectory() + @"\Msgs\" 

  //dir is then the value of the current exe's path, which is
  //d:\sourcecode\myproject\TestResults\myComputer 2009-10-08 16_07_45\Out

  //we actually need:
  //d:\sourcecode\myproject\Msgs\ 
  doc.Load( dir + fileName); //should really use System.IO.Path.Combine()!

将这条路径放在app.config中只是一件简单的事吗?考虑到开发者机器上不同路径的可能性,我希望避免这种情况。

问题:您如何编写算法以将单元测试方法中的给定Xml文件加载到XmlDocument中?

7 个答案:

答案 0 :(得分:24)

有一个Visual Studio单元测试功能:DeploymentItemAttribute

我使用此功能将给定项目文件夹中的所有xml文件复制到单元测试输出文件夹,然后再测试是否存在所有必需文件。

您可以将此属性与单元测试一起使用,将特定文件从Project文件夹(或其他任何位置)复制到Unit Test输出文件夹。像这样:

[TestMethod()]
[DeploymentItem("MyProjectFolder\\SomeDataFolder\\somefile.txt", "SomeOutputSubdirectory")]
public void FindResourcefile_Test()
{
    string fileName = "SomeOutputSubdirectory\\somefile.txt";
    Assert.IsTrue(System.IO.File.Exists(fileName));
}

您还可以复制整个文件夹的内容:

[TestMethod()]
[DeploymentItem("MyProjectFolder\\SomeDataFolder\\", "SomeOutputSubdirectory")]
public void FindResourcefile_Test()
{
    string fileName = "SomeOutputSubdirectory\\someOtherFile.txt";
    Assert.IsTrue(System.IO.File.Exists(fileName));
}

第一个参数是源,第二个参数是目标文件夹。源是相对于您的解决方案文件夹(因此您可以访问正在测试的项目的单元测试项目),目标是相对于单元测试程序集的输出文件夹。

<强>更新

您需要在“测试设置”中启用“部署”才能使用此功能。这个MSDN页面解释了(这很简单):http://msdn.microsoft.com/en-us/library/ms182475(v=vs.90).aspx#EnableDisableDeploy

答案 1 :(得分:23)

您可以将这些文件构建到可执行文件中(将其“Build Action”属性设置为“Embedded Resource”),然后使用Assembly.GetManifestResourceStream method获取它们。

答案 2 :(得分:10)

在单元测试项目中添加一个构建后事件,将XML文件复制到输出目录。然后,您可以使用原始代码获取XML文件。

post build事件看起来像这样:

copy $(SolutionDir)file.xml $(ProjectDir)$(OutDir)file.xml

您可能还需要将其添加到您的路径中:

Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)

答案 3 :(得分:4)

我使用帮助程序类来处理我可能想要在单元测试中访问的基本路径。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Brass9.Testing
{
    public static class TestHelper
    {
        public static string GetBinPath()
        {
            return System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
        }

        public static string GetProjectPath()
        {
            string appRoot = GetBinPath();
            var dir = new DirectoryInfo(appRoot).Parent.Parent.Parent;
            var name = dir.Name;
            return dir.FullName + @"\" + name + @"\";
        }

        public static string GetTestProjectPath()
        {
            string appRoot = GetBinPath();
            var dir = new DirectoryInfo(appRoot).Parent.Parent;
            return dir.FullName + @"\";
        }

        public static string GetMainProjectPath()
        {
            string testProjectPath = GetTestProjectPath();
            // Just hope it ends in the standard .Tests, lop it off, done.
            string path = testProjectPath.Substring(0, testProjectPath.Length - 7) + @"\";
            return path;
        }
    }
}

有时我与路径的互动更复杂;我经常使用一个名为“App”的中心类来表示应用程序的一些基本细节,比如它的根文件夹,根命名空间和模块等。类有时会依赖于App的存在,所以我会放置一个init App上使用上述代码初始化测试工具的方法,并在单元测试中从Init命令调用该方法。

(更新)

旧答案

我发现这有助于获取任意路径来访问您要测试的项目文件夹中的文件(而不是Test项目文件夹中的文件,如果您需要复制内容,可以使繁忙工作)。

DirectoryInfo projectDir = new DirectoryInfo(@"..\..\..\ProjectName");
string projectDirPath = projectDir.FullName;

然后,您可以使用这些变量中的任何一个来从相关项目中访问您需要的任何内容。显然,将“ProjectName”换成项目的实际名称。

答案 4 :(得分:1)

资源只是资源而且就是这样,不需要复杂化。如果您不想嵌入它们,则可以将这些文件作为“内容”资源添加到项目中,并将它们设置为Copy always。然后在代码中指定子文件夹:

var xmlDoc = XElement.Load("ProjectSubFolder\\Resource.xml");

这将自动从项目输出(运行装配位置)bin\$(Configuration)\ResourceSubfolder\

加载资源

这适用于所有类型的项目,而不仅仅是单元测试。

答案 5 :(得分:0)

我只是将路径放在app.config中并从默认路径加载。在我的团队中,我真的很嘲笑开发人员改变路径,所以我让我的所有开发人员在他们的计算机上拥有相同的路径和文件,所以我没有任何流氓开发人员改变路径以适应他的工作空间的问题。

例如,我团队中的所有开发人员都必须使用C:\ Project \ Product \ Module等。我还要确保他们安装的所有软件都是标准的。通过这种方式,我可以轻松地将任何机器变成任何其他机器。

答案 6 :(得分:0)

我认为在VS.NET 2012中,DeploymentItem属性在没有任何测试设置配置的情况下工作。