C# ~ NUnit單元測試

0. 單元測試 

  單元測試(Unit Test)的一個測試用例(Test Case)是一小段代碼,用於測試一個小的程序功能的行爲是否正常,保證開發的功能子項能正確完成並實現其基本功能。一個單元測試是用於判斷某個特定條件下某個特定函數的行爲。單元測試是隨功能代碼一起的一個配套工具,再配合面向接口編程方法Mock技術,大大提高代碼的可測試性。
 ·  白盒測試:測試單元的內部結構;
 ·  黑盒測試:測試單元的功能和可觀測行爲;

1. NUnit是什麼  

  NUnit 免費開源 (http://www.nunit.org),提供一套單元測試框架(專用於.Net的白盒測試架構)和一個測試運行程序(test runner)。其中,test tunner 用於尋找具有[TestFixture]屬性的類和類中的[Test]方法。  

2. TDD思想

  在功能代碼未完成前,先進行測試代碼的編寫;測試不應着眼於功能代碼,應着眼於設計。定義TDD的2個原則:
 ·  除非你有一個失敗的自動測試,永遠不要寫一單行代碼;
 ·  阻止重複;

3. 使用NUnit

 測試原則
  ·  可靠性、可維護性、可讀性;
  ·  儘量避免測試中的邏輯,一個單元測試應該是一系列的方法調用和斷言;
  ·  避免重複代碼;
  ·測試隔離,低耦合,防止不同測試之間的互相影響;
    
 NUnit屬性
 所有NUnit屬性都包含在 Nunit.Framework 命名空間裏,同時必須引用程序集 Nunit.Framework.dll。在項目測試時,有時要用到數據庫鏈接,一般將數據庫鏈接串放到Web.config配置文件裏,再通過
  System.Configuration.ConfigurationSettings.AppSettings[“DBConnectionString”].ToString();
獲取,但是在測試中是讀不到這個值的,測試時要把鏈接寫成固定字符串。
 ·TestFixture 
  修飾測試類。類必須爲public且必須有一個默認構造函數。
 ·Test 
  修飾測試方法。測試方法的返回值必須爲void。
 ·TestCase 
  修飾測試方法。標記方法具有參數並提供測試時需要的參數。
  [TestCase(參數列表)]
 ·Values 
  標記作爲測試方法的一系列的參數。
 ·Combinatorial
  測試時需要測試的各種可能的組合;
  [Test, Combinatorial]
  public void TestFunction01( [Values(1,2,3)]int val, [Values(“you”,”hi”)]string str ) {}
 ·SetUp/TearDown 
  修飾方法,測試類初始化/資源釋放函數。每個測試方法被調用之前/後執行,用於環境的建立/清理、初始化/釋放資源。屬性從任何的基類繼承而來,被修飾的方法必須爲public。
 · [TestFixtureSetUp/TestFixtureTearDown] OneTimeSetUp/OneTimeTearDown 
  修飾方法,測試用例初始化/資源釋放函數。任何測試方法被調用之前/後執行,類似構造/析構函數,其作用於整個[TestFixture]類,包括數據庫連接等,被修飾的方法必須爲public。
  SetUp/TearDown方法提供達到測試隔離性的目的:SetUp確保共享的資源在每個測試運行前正確初始化,TearDown確保沒有因運行測試產生的遺留副作用;TestFixtureSetUp/TestFixtureTearDown同樣提供相同的目的,但是卻在SetUp/TearDown方法之前/後。
 ·Ignore
  修飾類或方法,保證測試正常進行的前提下,臨時動態忽略某些測試方法。
  [Ignore(“提示信息”)]
 ·Category
  修飾類或方法,分類/分組管理測試類或方法;
  [Category(標籤)]

 NUnit方法
 在NUnit中,Assert(斷言)是一個類,斷言是Assert類的靜態方法。斷言是單元測試的核心,用類中的各種方法進行比較,也可以在NUnit的斷言中添加自己的錯誤信息。注意以下幾個方法:
 ·Assert.Fail():讓測試直接失敗;
 ·Assert.Ignore():讓測試被忽略;
 ·Assert.AreEqual/AreNotEqual (object expected, object actual)
   比較參數expected和actual的值(類型)是否相等;
 ·Assert.IsTrue/IsFalse (bool condition)
   條件斷言測試;
 ·Assert.AreSame/AreNotSame (object expected, object actual)
   比較兩個參數是否引用同一個對象;
 另外,還有StringAssert類,字符串斷言,提供對字符串值的測試方法。
 如果一個方法中有多個斷言,某個斷言執行失敗,在其之後的所有斷言都不會執行。具體的,NUnit~Assert類

 NUnit ~ 測試集管理
 NUnit的很多功能是通過屬性來實現,屬性是在.NET組件文件的Metadata中添加的一些可以被其他組件讀取的信息,用中括號標識。NUnit根據測試組件的命名空間及[TestFixture]和[Test]屬性來分類不同的測試。
  ·測試分類
  ·分組運行

 NUnit ~ Demo
 單元測試項目文件推薦命名:項目名稱_Test,源文件基本結構如下:

[TestFixture]
public class TestFunction
{
    [OneTimeSetUp]
    public void TestFixtureSetUp() { Console.WriteLine("OneTimeSetUp()"); }
    [OneTimeTearDown]
    public void TestFixtureTearDown() { Console.WriteLine("OneTimeTearDown()"); }

    [SetUp]
    public void SetUp() { Console.WriteLine("SetUp()"); }
    [TearDown]
    public void TearDown() { Console.WriteLine("TearDown()"); }

    [Test]
    public void TestMethod01() { Console.WriteLine("TestMethod01()"); }
    [Test]
    public void TestMethod02() { Console.WriteLine("TestMethod02()"); }
}

 測試幾個方法的執行順序:
 OneTimeSetUp -> SetUp -> TestMethod01 -> TearDown -> SetUp -> TestMethod02 -> TearDown -> OneTimeTearDown
 此處可以結合不足之處的第2點理解。
 
 NUnit ~ 單步調試
 單元測試之單步調試設置方法參考如下鏈接:
 http://www.cnblogs.com/ywqu/archive/2009/11/04/lindongshenghuo.html
   
 不足之處
  1. xUnit體系中JUnit是在測試每個方法時新生成一個實例,而NUnit中是一個TestFixture只生成一個實例。如果對包含單元測試類中的實例數據進行更改可能會影響到其它的測試方法,而JUnit每次都生成一個實例則不會產生這種情況。
  2. JUnit中[SetUp]/[TearDown]只會在所有測試前、後分別執行一次,而NUnit是在每個測試前、後都會執行一次,爲了達到JUnit中[SetUp]/[TearDown]的效果,能新增[TestFixtureSetUp]/[TestFixtureTearDown]屬性。


參考鏈接

[1]. 單元測試之道(使用NUnit)
[2]. 用NUnit在單元測試中實現構造函數依賴注入
[3]. NUnit單元測試教程以及Mock測試

發佈了60 篇原創文章 · 獲贊 21 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章