如何从Visual Studio中的Xunit测试中引用测试文件?

时间:2014-05-07 10:49:45

标签: visual-studio-2013 xunit.net

我们正在使用Xunit进行测试。我们使用Xunit插件通过内置的Visual Studio 2013 Test Runner运行我们的测试。

问题是某些测试需要引用文件系统上的文件。似乎Xunit(或VS Test Runner-不确定哪个)在执行测试之前将bin目录中的汇编(而不是bin目录中的任何支持文件)复制到另一个目录,因此找不到我们的测试文件。 [MS Testing框架指定列出要复制的文件的属性,但Xunit没有。]

如何 禁用此复制行为,或者以编程方式确定原始bin/目录位置以获取文件?

似乎大多数提议的解决方案(包括在Xunit错误跟踪器网站上)建议将文件存储为嵌入式资源而不是“复制始终”文件。但是,这并不总是实用的,例如:测试文件操作代码,以及(在一种情况下)需要Sqlite数据库文件的代码。

5 个答案:

答案 0 :(得分:30)

好的,典型的,就在我发布问题时,我自己找到答案......

要点是程序集的复制(阴影复制)似乎是由.NET框架完成的,而不是由Visual Studio或Xunit完成的。​​

我们一直在使用Assembly.Location来查找程序集文件,从而找到测试文件。但是,这是错误的,因为它给了我们Shadow-Copied组件的位置而不是原件。

相反,您应该使用Assembly.CodeBase来获取基本汇编代码位置。但是,这是一个(文件)URL,因此有必要从URL中提取路径。新的(C#)代码如下所示:

var codeBaseUrl = new Uri(Assembly.GetExecutingAssembly().CodeBase);
var codeBasePath = Uri.UnescapeDataString(codeBaseUrl.AbsolutePath);
var dirPath = Path.GetDirectoryName(codeBasePath);
return Path.Combine(dirPath, relativePath);

...其中relativePath是相对于Bin\目录的路径。

答案 1 :(得分:11)

经过一些搜索后,我在这里找到了解决方案:https://msdn.microsoft.com/en-us/library/ms182475.aspx

特别是,第一步对我来说已经足够了:

  

如果它们特定于一个测试项目,请将它们作为内容文件包含在Visual Studio测试项目中。在“解决方案资源管理器”中选择它们,并将“复制到输出”属性设置为“复制为更新。”

与以下代码相关联:

var filename = "./Resources/fake.pdf"
File.OpenRead(filename)

The test project (note the Resource folder) Cfg of files in the resource folder

答案 2 :(得分:3)

我在Mac上运行.Net Core 1.0。 Assembly.GetExecutingAssembly不可用。我改为使用以下代码:

var location = typeof(YourClassName).GetTypeInfo().Assembly.Location;
var dirPath = Path.GetDirectoryName(location);
return Path.Combine(dirPath, relativePath);

relativePath是相对于DLL目录的路径。

答案 3 :(得分:3)

在尝试识别目录和复制文件(似乎有多个目录,很难确定正确的目录)后,我发现您可以关闭卷影复制功能。此时,单元将再次测试bin / {configuration}文件夹中的参考内容。

要这样做,请遵循指示here。好像将shadowCopy设置为false一样简单:

{
    "shadowCopy": false
}

我不清楚此设置是否与其他设置(例如appDomain)有任何不利的相互作用。如果有人知道,将欢迎您发表评论。

答案 4 :(得分:2)

.NET5(可能更早)开始,CodeBase 不再有效,因此现在的解决方案是先将您的所有文件复制到 bin 目录并将其用作您的已知位置。

现在让这一切正常的原因是,您可以轻松地从 csproj 文件中将目录复制到 bin 文件夹中,这在过去总是令人头疼。

<ItemGroup>
  <None 
     Include="TestFiles\**" 
     CopyToOutputDirectory="PreserveNewest" 
     LinkBase="TestFiles\" />
</ItemGroup>

其中 TestFiles 位于项目文件夹的根目录中。现在您可以使用以下辅助方法访问这些文件。

public static class TestUtils
{
    public static string GetTestPath(string relativePath)
    {
        var codeBaseUrl = new Uri(Assembly.GetExecutingAssembly().Location);
        var codeBasePath = Uri.UnescapeDataString(codeBaseUrl.AbsolutePath);
        var dirPath = Path.GetDirectoryName(codeBasePath);
        return Path.Combine(dirPath, "TestFiles", relativePath);
    }
}