24

目标是在给定这些 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 中?

4

7 回答 7

26

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

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

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

[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

于 2012-07-25T11:35:52.553 回答
24

您可以将这些文件构建到您的可执行文件中(将它们的“构建操作”属性设置为“嵌入式资源”),然后使用Assembly.GetManifestResourceStream method.

于 2009-10-08T23:44:41.253 回答
11

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

构建后事件将如下所示:

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

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

Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
于 2009-10-08T23:54:08.090 回答
5

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

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 命令调用该方法。

(更新)

旧答案

我发现这有助于获取任意路径来访问您打算测试的项目文件夹中的文件(与测试项目文件夹中的文件相反,如果您需要复制内容,这可能会使工作变得忙碌)。

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

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

于 2011-03-30T00:28:25.640 回答
1

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

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

这将自动从项目输出(运行程序集位置)加载资源bin\$(Configuration)\ResourceSubfolder\

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

于 2014-04-09T23:03:30.630 回答
0

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

例如,我团队中的所有开发人员都必须使用 C:\Project\Product\Module 等。我还确保他们安装的所有软件也是标准的。这样,我可以轻松地将任何机器幻像到任何其他机器中。

于 2009-10-08T23:37:52.603 回答
0

我认为在 VS.NET 2012 DeploymentItem 属性中无需任何测试设置配置即可工作。

于 2013-08-26T20:22:10.603 回答