2008-10-10 46 views
9

我在Visual Studio 2008裏面使用了MSTEST。我如何讓每個單元測試方法在某個測試類中運行,就好像它是第一次運行測試一樣,以便在運行每個測試之前重置所有全局狀態?我不想使用TestInitialize,ClassInitialize,AssemblyInitialize等。例如明確清理世界:如何在運行之前強制MSTEST TestMethod重置所有單例/靜態?

[TestClass] 
public class MyClassTests 
{ 
    [TestMethod] 
    public void Test1() 
    { 
     // The "Instance" property creates a new instance of "SomeSingleton" 
     // if it hasn't been created before. 
     var i1 = SomeSingleton.Instance; 
     ... 
    } 
    [TestMethod] 
    public void Test2() 
    { 
     // When I select "Test1" and "Test2" to run, I'd like Test2 
     // to have a new AppDomain feel so that the static variable inside 
     // of "SomeSingleton" is reset (it was previously set in Test1) on 
     // the call to ".Instance" 
     var i2 = SomeSingleton.Instance; 
     // some code 
    } 

雖然similar question上出現了這個話題,只澄清,測試不平行運行。我意識到測試是連續運行的,但似乎沒有辦法爲每個方法明確強制一個新的AppDomain(或者相當於清除所有狀態的東西)。

理想情況下,我想爲我的單元測試的一小部分指定此行爲,這樣我就不必爲不關心全局狀態的測試支付新的AppDomain創建懲罰(絕大多數我的測試)。

回答

6

最後,我寫了一個幫助器,使用AppDomain.CreateDomain,然後使用反射調用另一個AppDomain下的單元測試。它提供了我需要的隔離。

This post在MSDN的論壇上展示瞭如何處理這種情況,如果你只有一些靜態需要重置。 It確實提到了一些選項(例如使用反射和PrivateType)。

我繼續歡迎任何進一步的想法,特別是如果我錯過了關於MSTEST的一些明顯的事情。

+2

你有代碼示例Jeff嗎? – DevDave 2012-04-30 10:49:43

+1

是的,一個代碼示例請 – Harindaka 2013-02-03 09:47:39

0

我們有一個類似的問題與我們的MSTests出現。我們通過在需要它的特定測試的開始和結束處調用一個函數來處理它。

我們正在我們的應用配置中存儲測試到期日期。三次測試需要這個日期落入特定的範圍以確定合適的值。我們的應用程序設置的方式,只有在會話中沒有賦值時纔會重置配置值。因此,我們創建了兩個新的私有靜態函數 - 一個用於顯式地將配置值設置爲指定日期,另一個用於在測試運行後從會話中清除該日期。在我們的三個測試中,我們稱這兩個函數。當下一個測試運行時,應用程序會看到日期的空值並從配置文件中重新獲取。

我不確定這是否有幫助,但這是我們如何解決類似問題的方法。

+0

好像你可能可以使用[TestInitialize]在你的測試課上? – 2008-10-13 17:30:09

0

我想你正在尋找TestIntialize屬性和TestCleanUp屬性。這是一個顯示執行順序的MSDN博客link text

+0

感謝您的回答。我一直在尋找能夠清理世界而不必明確清除每個變量的東西,但我不確定這是否可行。 – 2008-10-13 17:28:09

3

在使用反射刪除單例實例的測試中添加一個幫助器(您也可以向單例添加一個重置方法,但我會擔心它的使用)。例如:

public static class SingletonHelper { 
      public static void CleanDALFactory() 
      { 
        typeof(DalFactory) 
         .GetField("_instance",BindingFlags.Static | BindingFlags.NonPublic) 
         .SetValue(null, null); 
      } 
} 

在您的TestInitialize方法中調用此方法。 [我知道這是「清理世界」,但你只需要在每個單身人員的助手中寫一次方法,這非常簡單,並給你明確的控制]

相關問題