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
System.Configuration.ConfigurationSettings.AppSettings[“DBConnectionString”].ToString();
獲取,但是在測試中是讀不到這個值的,測試時要把連結寫成固定字串。
· TestFixture
修飾測試類。類必須為public且必須有一個預設建構函式。
· Test
修飾測試方法。測試方法的返回值必須為void。
· TestCase
修飾測試方法。標記方法具有引數並提供測試時需要的引數。
[TestCase(引數列表)]
·
標記作為測試方法的一系列的引數。
· 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]屬性。