如何为每个xUnit.net测试方法使用单独的AppDomain?

时间:2014-01-20 15:31:19

标签: c# .net xunit.net

xUnit对整个测试程序集使用相同的AppDomain,这是有问题的,因为我正在测试UI库并需要为每个单独的测试创建一个新的Application实例。

当我运行单个测试时,但是当我Run All第一次测试通过时,它会起作用,但是所有后续测试都在我创建新Cannot create more than one System.Windows.Application instance in the same AppDomain对象的行中Application失败

3 个答案:

答案 0 :(得分:6)

也许你可以试试这样的测试class

public class DomainIsolatedTests : IDisposable
{
  private static int index = 0;
  private readonly AppDomain testDomain;

  public DomainIsolatedTests()
  {
    var name= string.Concat("TestDomain #", ++index);
    testDomain = AppDomain.CreateDomain(name, AppDomain.CurrentDomain.Evidence, AppDomain.CurrentDomain.SetupInformation);
    // Trace.WriteLine(string.Format("[{0}] Created.", testDomain.FriendlyName)); 
  }

  public void Dispose()
  {
    if (testDomain != null)
    {        
      // Trace.WriteLine(string.Format("[{0}] Unloading.", testDomain.FriendlyName));
      AppDomain.Unload(testDomain);        
    }
  }

  [Fact]
  public void Test1()
  {
    testDomain.DoCallBack(() => {
      var app = new System.Windows.Application();

      ...
      // assert
    });
  }

  [Fact]
  public void Test2()
  {
    testDomain.DoCallBack(() => { 
      var app = new System.Windows.Application();

      ...
      // assert
    });
  }

  [Fact]
  public void Test3()
  {
    testDomain.DoCallBack(() => {
      var app = new System.Windows.Application();

      ...
      // assert
    });
  }

  ...
}

答案 1 :(得分:0)

也许,foreach测试您可以在新域中动态加载程序集。

public static void DynamicExecution(String assemblyFileName, String uniqueDomName)
{
    Boolean retVal = false;

        AppDomain newDomain = AppDomain.CreateDomain(uniqueDomName);
        YourClass yourClass = (YourClass)newDomain.CreateInstanceFromAndUnwrap(assemblyFileName, "YourClass");

        //do what you need with yourClass Object


        AppDomain.Unload(newDomain);
        newDomain = null;
}

答案 2 :(得分:0)

AppDomain appDomain = AppDomain.CreateDomain("WorkerDomain " + Thread.CurrentThread.Name);

var domain = (AppDomainWorker)appDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(AppDomainWorker).FullName);

domain.Executor();

internal class AppDomainWorker
{
    internal object Executor ()
    {
        // your unit test can run here
    }
}

两个更重要的事情:

1)您可能需要将类标记为MarshalByRefObject并覆盖InitializeLifetimeService方法以使对象具有更长的生命或存在。如果您必须在appdomains之间进行通信,则需要MarshalByRefObject。有关此远程读取Microsoft远程处理概念的详细信息。

2)有时我们可能需要在AppDomains中进行程序集解析,如果它没有在父域中加载程序集,但在极少数情况下。