2016-11-09 44 views
0

我想在NUnit中使用TestCaseSource運行多個測試。但我很努力讓[SetUp]在我需要時運行。正確的方式運行測試設置與Nunit TestCaseSource

目前它的工作方式我想要它,但它不覺得「正確」。所以,下面是主要的測試案例代碼(簡體):

public class ImportTestCases 
{ 

    ImportTestCases() 
    { 
     TestData.RunTestSetup(); 
    } 

    public static IEnumerable TestCases 
    { 
     get 
     { 
      //run the funciton under test... 
      var results = RunFunctionSubjectToTest(TestData.ImportantVar); 

      //get multiple results... 
      var allProperties =new TestCaseData(o).Returns(true) 
       ExpandNestedProperties(results.AllProperties) 
        .ToList() 
        .ConvertAll(o => new TestCaseData(o).Returns(true)); 

      return allProperties; 
     } 
    } 


} 


[TestFixture] 
public class ImportTests 
{ 

    [TestFixtureSetUp] 
    public void ImporTestSetup() 
    { 
     TestData.RunTestSetup(); 
    } 

    [Test, TestCaseSource(typeof(ImportTestCases), nameof(ImportTestCases.TestCases))] 
    public bool PropertyTest(UnitTestHelper.PropInfo info) 
    { 
     return info.DoTheyMatch; 
    } 

} 

這裏的問題是,[設置]之前沒有ImportTestCases「的TestCase」 財產「得到」的跑了跑。 「ImportTestCases」的構造函數也沒有運行。所以,爲了保證ImportVar引用之前,我需要做下面的「RunTestSetup」是跑:

public static class TestData 
{ 
    private static bool HasSetUpRan = false; 
    private static int _importantVar; 
    public static int ImportantVar 
    { 
     get 
     { 
      if(!HasSetUpRan) 
      { 
       RunTestSetup(); 
      } 
      return _importantVar; 
     } 
    }   
    public static void RunTestSetup() 
    { 
     if (HasSetUpRan) 
     { 
      return; 
     } 
     ///do set up 
     //e.g. _importantVar = GenerateId(); 
     //end 
     HasSetUpRan= true; 
    } 

} 

正如你可以看到這保證了成立以來跑返回變量之前。可悲的是,這是我成功實現目標的唯一途徑。正如我所說的那樣,感覺「錯誤」並且過於複雜。也許我在這裏過度使用測試用具?或者我應該使用某種形式化的測試用例(可能嗎?)。

我試圖簡化上面的代碼,所以道歉,如果它根本沒有意義,我試圖測試。

主要點是否有一個[Setup]在TestCaseSources創建之前運行?

回答

0

也許一種可能的解決方案可能是使您的方法創建TestSource不是靜態的並添加默認構造函數。在構造函數中,可以完成測試用例所需的所有初始化工作。你仍然可以使用TestFixtureSetUp來進行其他初始化工作。

[TestFixture] 
public class ImportTests 
{ 
    public ImportTests() 
    { 
     //inititalize test case source 
    } 

    [TestFixtureSetUp] 
    public void ImporTestSetup() 
    { 
     //inititalize rest of test 
    } 

    public IEnumerable<string> Fields() 
    { 
     return new[] { "foo", "bar", "foobar" }; 
    } 

    [Test] 
    [TestCaseSource("Fields")] 
    public void PropertyTest(string info) 
    { 
     // Assert 
    } 
} 
0

重點是測試用例將在加載測試時定位。因此,在調用「TestCases」屬性後,將執行具有[TestFixtureSetUp]屬性的例程。但是你可以在靜態構造函數中執行一些設置例程。但爲了先調用它,你需要把你的測試數據在同級別:

[TestFixture] 
public class ImportTests 
{ 
    static ImportTests() 
    { 
     //Step 1 
     //run your set-up routine 
    } 

    //Step 3 
    [Test, TestCaseSource(nameof(ImportTests.TestCases))] 
    public bool PropertyTest(string s) => string.IsNullOrEmpty(s); 

    //Step 2 
    public static IEnumerable TestCases => new[] {new TestCaseData("").Returns(true)}; 
} 
+0

這絕對解決了這個問題,而不需要布爾的東西:)。我會試着理解Charlies回答多一點,看看我是否做錯了:) – chrispepper1989

1

什麼你正在嘗試基本上做忽略NUnit的是如何工作的。考慮這個序列:

  1. 您運行GUI並加載測試程序集。
  2. 爲了給gui一個測試列表,NUnit執行你的TestCaseSource方法。
  3. 您的測試用例源方法確定將有多少測試以及哪些參數傳遞給每個測試用例。
  4. 你可以坐在辦公桌前查看所有測試的名稱,或者在twitter上發帖。假設20分鐘。
  5. 您運行所有測試,導致SetUp,TearDown和測試方法本身執行。
  6. 你去吃午飯。
  7. 午餐後,您決定再次運行測試。所有相同的SetUp,TestMethod,TearDown都會再次執行。只要您沒有重新編譯重新加載測試程序集,就不會再使用測試用例源代碼。

當決定在你的測試用例源代碼中做什麼時,你必須意識到這個序列,我誇大其結果。通常,創建長壽命對象可能不是您想要做的事。

一些更多的注意事項:

  • 在NUnit的,測試用例幾乎都是參數。如果測試沒有參數化,那麼它不需要源,但可以只是一個簡單的測試,並且可以完成它自己的初始化。

  • 標記與測試和源代碼相同的方法,如某人所建議的那樣是一個非常大的錯誤 - 病態。我們不把它看作一個錯誤的唯一原因是,幾乎沒有人試圖這樣做,因爲測試方法和測試用例源方法的目的完全不同。

最好的辦法是使用源代碼返回測試可用於實例化您需要的對象的參數。

+0

嗨查理,謝謝你的回答,但我不確定我們是否在交叉目的談話。我特別不想在測試用例中創建一個長壽命的對象,我希望在設置時發生這種情況,但我需要該對象來生成我的測試用例,因爲它有助於創建我的參數。下面的靜態構造函數的答案當然是更好的解決方案,我已經在上面了,這是我現在要運行的。但我很想知道是否有「TestFixturePreTestCaseSetUp」。但是根據你的說法,這似乎不是這樣? – chrispepper1989