2014-01-20 30 views
13

xUnit對整個測試程序集使用相同的AppDomain,這是有問題的,因爲我正在測試UI庫並需要爲每個單獨的測試創建一個新的Application實例。如何爲每個xUnit.net測試方法使用單獨的AppDomain?

它運行時,我運行一個單一的測試,但當我Run All第一次測試通過,但所有後續測試失敗Cannot create more than one System.Windows.Application instance in the same AppDomain在我創建一個新的Application對象的行。

+0

對於每個測試(即測試方法)或每個文本「夾具」 –

+2

@PeterRitchie對於每個測試方法(情況) – Flagbug

+2

http://patrick.lioi.net/2013/04/18/isolating-execution/ –

回答

5

或許你可以嘗試讓你的測試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 
    }); 
    } 

    ... 
} 
+2

嗯,這個「工作」,但問題是,即使一個測試在DoCallBack方法失敗,xUnit報告測試已成功。似乎吞噬了異常 – Flagbug

+0

@Flagbug你能舉一個你的_failing_測試的例子嗎? – IronGeek

+0

@Flugbug你設法傳播異常,所以xUnit可以檢測到它嗎? – khorvat

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; 
} 
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方法有一個對象更長生命或存在。如果您必須在應用程序域之間進行通信,則需要使用MarshalByRefObject。有關此詳細信息,請閱讀Microsoft遠程處理概念。

2)某些時候我們可能需要在AppDomain中進行程序集解析,如果它沒有將父程序集中的程序集加載,但是在極少數情況下。

相關問題