如何将非托管库引用添加到 NUnit 测试
Posted
技术标签:
【中文标题】如何将非托管库引用添加到 NUnit 测试【英文标题】:How to add unmanaged library reference to NUnit test 【发布时间】:2017-10-09 18:17:47 【问题描述】:问题:如何在运行测试时使 NUnit 可以使用本机库,以便在启动时加载它?
背景:我最近开始使用 NUnit 进行测试,我正在努力设置一个涉及非托管(本机)库的测试(我们称之为 x.dll
)。我正在测试的项目是围绕这个库的托管 c++/CLI 包装器。我有引用包装器的 NUnit c# 测试项目,所以我可以使用那里定义的函数。问题是我运行测试时,抛出System.IO.FileNotFoundException
,表示找不到x.dll
。我需要以某种方式将 NUnit 指向它的位置,或者让它将 dll 复制到执行目录中(隐藏在 temp
目录中的某处),但在相当广泛的搜索之后找不到如何做到这一点 - 可能缺少正确的关键字。
我在 Visual Studio 中使用 NUnit 3 扩展,并且测试项目是使用模板创建的,该模板也可用作扩展。
【问题讨论】:
【参考方案1】:使用非托管程序集的技巧是要知道操作系统使用与 .NET 查找托管引用的方式不同的方法来查找它们。
作为复习:在路径上找到非托管程序集,而在 AppBase 或它下的私有 binpath 中找到托管程序集。
我的猜测是 VS 正在将 x.dll
复制到输出目录中。如果没有,您应该通过将 CopyLocal 设置为 true 来实现。现在,在运行测试之前,将该目录添加到路径的开头。如果您还没有使用脚本,那么您可能必须创建一个才能执行此操作。
【讨论】:
我应该使用什么方法来编辑路径(我猜你的意思是环境变量)?是否可以仅在启动时为应用程序(测试)更改它,还是我必须在系统范围内对其进行编辑?我想要前者——不污染系统,也不强迫所有开发人员这样做,但我不确定它是否可行。 测试在加载之前无法执行任何操作,并且在满足所有引用之前无法加载。如果您运行脚本来执行测试,只需在运行 nunit3-console.exe 之前添加到 PATH 环境变量。脚本完成后,该设置不会影响其他任何内容。 谢谢,但我正在使用 Resharper 直接从 Visual Studio 运行测试。我如何将运行nunit3-console
的脚本与此环境集成?在旁注中,多亏了你的回顾,我可能已经设法准确地设置了我需要的东西,只需要在发布之前多尝试一下。【参考方案2】:
因为我希望测试是独立的并且能够使用 Resharper 或 Visual Studio 测试框架(使用 NUnit 扩展)等工具运行,所以我尽量避免像 @Charlie 建议的那样从脚本运行测试,因为我不会知道如何将结果与这些工具集成。
不过,我设法找到了一个有趣的属性OneTimeSetUpAttribute
,它可以用来标记函数,以便it will be ran every time before the tests。值得庆幸的是,这是在运行测试的同一进程中实现的,因此我们可以使用它以优雅的方式更改 Path 变量。这是我用来更改 Path 的代码,它还允许区分它们运行的架构:
void RegisterLibs()
const string pathVar = "Path";
const string fileUriTag = "file:///";
// Get executable path
var exePath = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
if (exePath.StartsWith(fileUriTag))
exePath = exePath.Remove(0, fileUriTag.Length);
// Extract directory
var exeDir = System.IO.Path.GetDirectoryName(exePath);
// Get path variable
var pathVal = Environment.GetEnvironmentVariable(pathVar) ?? "";
// Simple check for architecture.
// 4-byte pointer => 32bit
// 8-byte pointer => 64bit
var arch = IntPtr.Size == 4 ? "Win32" : "x64";
// Prepare new entry for path
var libPath = $"exeDir\\arch;";
if (pathVal.Contains(libPath))
return;
// Prepend the entry
pathVal = pathVal.Insert(0, libPath);
// Update path variable
Environment.SetEnvironmentVariable(pathVar, pathVal);
然后可以在测试中使用:
[TestFixture]
public class UnitTests
[OneTimeSetUpAttribute]
public void TestFixtureSetup()
RegisterLibs();
[Test]
public void Test1()
// Path is set-up here
// ...Your test code...
【讨论】:
以上是关于如何将非托管库引用添加到 NUnit 测试的主要内容,如果未能解决你的问题,请参考以下文章