2012-05-22 107 views
8

我在TeamTest中有一個名爲「MyClassTest」的單元測試項目。這個項目有三個TestMethods。每種方法都需要自己的測試初始化​​步驟。但是,當我將TestInitializeAttribute應用於三種初始化方法時,它說該屬性不應該被多次使用。那麼應該用什麼屬性來初始化Visual Studio Team Test中的每個測試方法?VS團隊測試:測試類中的多個測試初始化​​方法

參考:

  1. VS Team Test: .Net Unit Testing with Excel as Data Source: Adapter Failed

  2. How to create Startup and Cleanup script for Visual Studio Test Project?

  3. VS 2010 Load Tests Results with custom counters

  4. How to log unit test entry and leave in MSTest

  5. Can a unit test project load the target application's app.config file?

回答

18

根據MSDNTestInitializeAttribute

  • 不能使用超過一次(=的AllowMultiple假)和
  • 不能被繼承來創建自己的TestInitializeAttribute

所以,我的建議是創建沒有TestInitialize屬性的測試初始化​​方法。然後在獨特TestInitialize方法檢查這是目前執行TestMethod並調用相應的初始化方法:

[TestClass] 
public class UnitTest 
{ 
    public TestContext TestContext { get; set; } 

    [TestInitialize] 
    public void Initialize() 
    { 
     switch (TestContext.TestName) 
     { 
      case "TestMethod1": 
       this.IntializeTestMethod1(); 
       break; 
      case "TestMethod2": 
       this.IntializeTestMethod2(); 
       break; 
      default: 
       break; 
     } 
    } 

    [TestMethod] 
    public void TestMethod1() 
    { 
    } 

    [TestMethod] 
    public void TestMethod2() 
    { 
    } 

    public void IntializeTestMethod1() 
    { 
     //Initialize Test Method 1 
    } 

    public void IntializeTestMethod2() 
    { 
     //Initialize Test Method 2 
    } 
} 
+1

謝謝。這似乎是可行的。人們遵循的標準做法是什麼? – Lijo

+0

這是我的團隊遵循的做法。我不知道是否還有另一種更好的方法:) – Schaliasos

+5

'AllowMultiple = false'只在同一元素中強制執行單個用法......這意味着單個方法不能用多個'TestInitializeAttribute'標記。它不能用於不同方法的規則與'AllowMultiple = false'無關。 –

3

如果他們需要三個獨立的inits;那麼他們可能應該在三個獨立的燈具,每個都有自己的init!

+0

Schaliasos建議上述方法。這應該沒問題。你有沒有看到缺點? – Lijo

+2

不,不是。只要三個測試在邏輯上相關。我個人......我將它分成三個裝置,但這是個人喜好的事情。上面看起來很好。之後你還需要做測試清理嗎?可以使用相同的方法嗎? –

11

如果你有三個測試方法,並每種方法都有其自身的初始化步驟,那麼爲什麼你感動初始化到每次測試之前都會運行的方法?我看到的唯一好處就是那個不錯的開關塊,它在源文件中添加了一些行。但是它給你帶來了缺點 - 在這些測試方法的任何一個上看,你不能真正知道在哪個上下文方法將被執行。所以,我使用初始化方法來設置只有基礎上下文,這是所有測試夾具真正使用的。

只是將上下文創建移動到每個方法的arrange部分。

如果您有幾種使用公共上下文的方法,那麼只需提取方法,它將爲它們設置上下文,並在arrange部分調用它。您還可以將每個上下文設置分割爲幾個步驟,並重復使用這些步驟(例如在Given-When-Then工具(例如Specflow)中完成)。

而且,當然,創建不同的燈具也是選項。

+1

在通過集成測試進行負載測試的範圍內(例如在加載測試WCF服務層的情況下),您希望測試方法儘可能乾淨,因爲測試方法執行時間是要跟蹤的內容。這是一個明確的例子,移動所有初始化邏輯來測試初始化​​是唯一的方法! –

+1

@DavidRodrigues不僅。您可以爲正在測試的每個功能創建單獨的TestFixture類。這將是非常簡單的,它的SetUp方法將不會有任何開關塊。另外,我會用SpecFlow等東西進行驗收測試。有很好的給定的方法,很好地組織,可以重複使用。 SpecFlow將所有步驟執行時間寫入輸出窗口 –

4

這是一個有點老帖子,但我想出了這似乎工作確定如下: 首先,定義一個屬性類:

[AttributeUsage(AttributeTargets.Method, Inherited = true)] 
public class InitialiseWithAttribute : Attribute 
{ 
    public string Id { get; private set; } 

    public InitialiseWithAttribute(string id) 
    { 
     Id = id; 
    } 
} 

然後在一些方便的實用工具類中定義的擴展方法:

public static bool IsInitialisedWith(this string testName, string value) 
    { 
     bool result = false; 
     Type testClassType = new StackFrame(1).GetMethod().DeclaringType; 
     MethodInfo methodInfo = testClassType.GetMethod(testName); 
     if (methodInfo != null) 
     { 
      InitialiseWithAttribute initialiseWithAttribute = 
       methodInfo.GetCustomAttribute<InitialiseWithAttribute>(true); 
      if (initialiseWithAttribute != null) 
      { 
       result = initialiseWithAttribute.Id == value; 
      } 
     } 
     return result; 
    } 

現在寫你的測試,從而:

public TestContext TestContext {get; set;} 
    [TestInitialize] 
    public void TestInitialise() 
    { 
     if (TestContext.TestName.IsInitalisedWith("DoSomethingSpecial") 
     { 
      // ... Do something special 
     } 
     else 
     { 
      // ... Do something normal 
     } 
    } 

    [TestMethod] 
    [InitialiseWith("DoSomethingSpecial")] 
    public void MySpecialTest() 
    { 
     // The test 
    } 
2

在我的工作中,我們將參數傳遞給TestInitialize方法,以確定我們希望初始化如何工作。

public partial class CommonActions 
{ 
    public void TestInitialize(bool adminTest) 
    { 
     try 
     { 
     if (adminTest) 
     { 
      //do stuff 
     } 

然後我們在類定義中有一個標準的初始化,默認爲false。

[TestClass] 
public class ProjectTestBase : FrameworkTestBase 
{ 
    public CommonActions common { get; set; } = new CommonActions(); 

    [TestInitialize] 
    public void TestInitialize() => common.TestInitialize(false); 

然後在測試案例中,您可以覆蓋TestInitialize以進行任何您想要的測試。

[TestClass] 
public class SetReportsInAdmin : ProjectTestBase 
{ 
    [TestInitialize] 
    public new void TestInitialize() => common.TestInitialize(true); 

我們使用布爾值來判斷Admin測試是否需要額外的安裝開銷。以這種方式應用所需的任何變量,並通過使用一種方法爲您提供多個初始化。

相關問題