我有一个带有两个nuget包的测试项目Proj_Test
。
<packages>
<package id="NUnit" version="3.6.0" targetFramework="net45" />
<package id="NUnit3TestAdapter" version="3.6.0" targetFramework="net45" />
</packages>
Proj
引用了其他几个需要加载的dll。
我在哪里可以添加此信息,以便我可以在IDE中使用NUnit3TestAdapter启动测试,而无需将dll实际复制到输出文件夹。
有a solution for the Nunit2 Runners。但是当我尝试通过NUnit3TestAdapter将其用于Nunit3时,我失败了。
根据tips and tricks section我通过菜单添加了设置文件Test.runsettings
。
<RunSettings>
<NUnit>
<PrivateBinPath>D:\Drive\AnyThirdParty</PrivateBinPath>
</NUnit>
</RunSettings>
设置似乎被忽略了。
如何为我的测试管理这些依赖项?
编辑: This is我发生了什么事。
专用程序集部署在与应用程序相同的目录结构中。如果为PrivateBinPath指定的目录不在ApplicationBase下,则忽略它们。
创建副本真的是唯一的解决方案吗?
答案 0 :(得分:1)
如果找不到更好的东西,请尝试自行解决
using ConsoleApplication6;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Reflection;
namespace UnitTestProject1
{
[TestClass]
public class UnitTest1
{
[TestInitialize]
public void Init()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += MyResolveEventHandler;
}
[TestMethod]
public void TestMethod1() { Assert.AreEqual(new MyClass().DoSomething(), 1); }
[TestMethod]
public void TestMethod2() { Assert.AreEqual(new MyClass().DoSomething(), 1); }
private Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
{
return Assembly.LoadFile(@"C:\MyPath\MyAssembly.dll");
}
}
}
不幸的是,程序集探测仅适用于子目录,因此您无法使用它...
答案 1 :(得分:1)
感谢George Vovos的回答,这就是我最终实施的目标。
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
//https://github.com/nunit/docs/wiki/SetUpFixture-Attribute
//A SetUpFixture outside of any namespace provides SetUp and TearDown for the entire assembly.
[SetUpFixture]
class GlobalSetup
{
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern int SetDllDirectory(string NewDirectory);
static HashSet<string> directories = new HashSet<string>
{
@"D:\Drive\AnyThirdParty\"
};
[OneTimeSetUp]
public void RunBeforeAnyTests()
{
AddManagedHandler();
SetNativeDirectories();
}
private void SetNativeDirectories()
{
if(directories.Count() != 1)
{
//TODO: add support for multiple directories
throw new NotImplementedException("current implementation only supports exactly one directory");
}
if (0 == SetDllDirectory(directories.First()))
{
throw new Exception("SetDllDirectory failed with error " + Marshal.GetLastWin32Error());
}
}
private void AddManagedHandler()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
IEnumerable<string> candidates = FindCandidates(new AssemblyName(args.Name));
return Assembly.LoadFrom(candidates.First());
}
private static IEnumerable<string> FindCandidates(AssemblyName assemblyname)
{
List<string> candidates = new List<string>();
foreach (var path in directories)
{
string candidate = string.Format(@"{0}{1}.dll", path, assemblyname.Name);
if (File.Exists(candidate))
{
candidates.Add(candidate);
}
}
if (!candidates.Any())
{
throw new FileNotFoundException(string.Format("Can not find assembly: '{0}.dll'", assemblyname.Name));
}
return candidates;
}
}