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

p.c*_*ell 22 c# unit-testing filepath visual-studio

目标是在这些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()!
Run Code Online (Sandbox Code Playgroud)

只是将这条路径放在一个简单的问题上app.config?考虑到开发人员机器上存在不同路径的可能性,我希望避免这种情况.

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

Pie*_*ler 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));
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

更新:

您需要在"测试设置"中启用"部署"才能使其生效.这个MSDN页面解释如何(这是真正的轻松):http://msdn.microsoft.com/en-us/library/ms182475(v=vs.90).aspx#EnableDisableDeploy


Chr*_*isW 23

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


Hit*_*mer 10

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

post build事件看起来像这样:

copy $(SolutionDir)file.xml $(ProjectDir)$(OutDir)file.xml
Run Code Online (Sandbox Code Playgroud)

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

Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
Run Code Online (Sandbox Code Playgroud)

  • 我发现我的文件将转到"Project1_UnitTests\bin\Debug",而测试试图在"TestResults\Username_PCName_datetime\Out"下找到它.. ??? (14认同)
  • @DominicCronin这不是真的.如果数据文件是被测项目的一部分,它们将被复制到项目的调试文件夹中,但它们不会被复制到单元测试输出文件夹,这是单元测试期间执行组件的位置. (6认同)

Chr*_*ini 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

(更新)

旧答案

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

DirectoryInfo projectDir = new DirectoryInfo(@"..\..\..\ProjectName");
string projectDirPath = projectDir.FullName;
Run Code Online (Sandbox Code Playgroud)

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