單元測試作為提高代碼和軟體品質的有效途徑,其重要性和益處自不必多說,雖然我沒有實踐過TDD之類,但堅信單元測試的積極作用。作為一種開發方法,單元測試早在上世紀70年代就已經在Smalltalk語言被運用了,這麼多年來,單元測試一次又一次證明了自身的價值,在各種開發方式此起彼伏的浪潮中,經受住了時間的考驗。
現在,俺也開始學習了,并在以後好好實踐。這個系列的學習素材為Roy Osherove所著The Art of Unit Testing with examples in C#, 2nd Edition
一 單元測試基礎知識
單元測試是一段代碼調用另外一段代碼,随後檢驗一些假設的正确性。如果假設的結果錯了,單元測試會失敗,一個“單元”指的是一個方法或函數。
a) 優秀的單元測試具備如下特性
自動的、可重複的
容易實作
一旦寫好,将來都可使用
任何人都可運作
單擊一個按鈕就可運作
可以快速地運作
總之單元測試應該是全自動的、可信賴的、可讀性強的和可維護的。
但在判斷自己所寫的測試是否優秀的單元測試前,可通過思考下面的問題,來了解普通的軟體測試行為和單元測試之間的差別:
兩周或兩個月、甚至兩年前寫的單元測試,還可以運作并得到結果嗎?
兩個月前寫的單元測試,任何一個團隊成員都可以運作并得到結果嗎?
是否可以在幾分鐘内跑完所有的單元測試?
可以單擊一個按鈕就運作我所寫的單元測試嗎?
是否能在幾分鐘内寫一個基本的單元測試
如果這些問題有一個是否定的,那麼所做的測試就不是單元測試(而是內建測試)。
b) 一個單元測試通常包括三個主要部分:配置對象、操控對象、通過斷言判斷結果是否符合預期,這便是測試的基本模式Arrange-Act-Assert
c) 推薦的單元測試命名規範為:
項目名:被測項目.Tests,
類:被測類+Tests,通常一個被測類對應一個測試類
方法:被測方法_測試場景_預期行為,一個被測方法會有多個測試用例,每個測試用例又會針對不同的輸入,有不同的預期行為,是以一般一種預期行為對應一個測試方法
二 開始使用NUnit
XUnit系列作為優秀的單元測試工具被廣泛使用。需要下載下傳并在單元測試項目中引用nunit.Framework.dll,然後VS需要安裝NUnit Adapter 3擴充工具,這樣NUnit就替代MS Test作為預設的測試工具了。
a) Nunit特性标簽
NUnit利用Attribute标簽辨別要運作的測試,[TestFixture]用來辨別測試類,[Test]則用來辨別測試方法
可以通過[Category]标簽為測試方法分組
暫時不需要測試的方法可以标記為[Ignore]
b) 對于單元測試,有兩點十分重要:
及時清理前一個測試遺留的任何資料或執行個體對象
為新的測試重新設定狀态,就像之前沒有運作任何測試一樣
NUnit提供了[SetUp]和[TeatDown]來做到這兩點,被[SetUp]标記的方法會在每個[Test]方法運作前執行,而[TeatDown]則在[Test]方法之後執行。
另外還有[TestFixtureSetUp]和[TestFixtureTearDown],用來在測試類的前後執行。
c) Assert類
Assert類是NUnit單元測試的基礎,用來判斷假設條件是否成立。基本的Assert方法如下,其餘很多衍生的方法用法類似。
Assert.IsTrue 用來驗證條件表達式是否為真
Assert.AreEqual 驗證是否與期望值相等
Assert.AreSame驗證是否引用了同一個對象
參考資料:
The Art of Unit Testing with examples in C#, 2nd Edition by Roy Osherove