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

问题描述 投票:0回答:5

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

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

如何禁用此复制行为,或者以编程方式确定原始

bin/
目录位置来获取文件?

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

visual-studio-2013 xunit.net
5个回答
44
投票

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

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

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

与以下代码相关联:

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


42
投票

好吧,典型的,我一发布问题,我自己就找到了答案......

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

我们一直在使用

Assembly.Location
来定位程序集文件,从而找到测试文件。然而,这是错误的,因为它为我们提供了卷影复制组件的位置而不是原始组件的位置。

您应该使用

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\
目录的路径。


12
投票

.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);
        }
    }

3
投票

在努力尝试识别目录和复制文件之后(似乎有多个目录在起作用,很难确定正确的目录),我发现你可以关闭卷影复制;此时,单元测试将再次引用 bin/{configuration} 文件夹中的内容。

为此,请按照此处的说明进行操作。看起来就像将

shadowCopy
设置为 false 一样简单:

{
    "shadowCopy": false
}

我不清楚此设置是否与其他设置有任何不利的相互作用(例如

appDomain
)。如果有人知道,欢迎评论。


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 目录的路径。

© www.soinside.com 2019 - 2024. All rights reserved.