Visual Studio – unit testing在项目中加载资源

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

如何在unit testing方法中轻松地将给定的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只是一个简单的问题吗? 考虑到开发人员机器上可能存在不同的路径,我希望避免这种情况。

问题:在unit testing方法中,您如何编写算法将给定的Xml文件加载到XmlDocument中?

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

post build事件看起来像这样:

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

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

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

有一个Visual Studiounit testingfunction: DeploymentItemAttribute

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

您可以将此属性与unit testing一起使用,将特定文件从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)); } 

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

更新:

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

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

我使用辅助类来处理我可能想要在unit testing中访问的基本路径。

 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上的方法,它使用上面的代码为测试工具初始化自己,并在unit testing中从Init命令调用该方法。

(更新)

老答案

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

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

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

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

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

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

这适用于所有类型的项目,而不仅仅是unit testing。

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

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

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