1. 程式人生 > >.NET 專案中的單元測試

.NET 專案中的單元測試

# .NET 專案中的單元測試 ## Intro > “不會寫單元測試的程式設計師不是合格的程式設計師,不寫單元測試的程式設計師不是優秀的工程師。” > > —— 一隻想要成為一個優秀程式設計師的渣逼程式猿。 那麼問題來了,什麼是單元測試,如何做單元測試。 ## 單元測試 ### 單元測試的定義 按照維基百科上的說法,單元測試(Unit Testing)又稱為模組測試, 是針對程式模組(軟體設計的最小單位)來進行正確性檢驗的測試工作。 程式單元是應用的最小可測試部件。在面向物件程式設計中,最小單元就是方法,包括基類、抽象類、或者派生類(子類)中的方法。 按照通俗的理解,一個單元測試判斷某個特定場條件下某個特定方法的行為,如斐波那契數列演算法,氣泡排序演算法。 > 單元測試(unit testing),是指對軟體中的最小可測試單元進行檢查和驗證。 對於單元測試中單元的含義,一般來說,要根據實際情況去判定其具體含義, 如C語言中單元指一個函式,Java裡單元指一個類,圖形化的軟體中可以指一個視窗或一個選單等。 總的來說,單元就是人為規定的最小的被測功能模組。 單元測試是在軟體開發過程中要進行的最低級別的測試活動,軟體的獨立單元將在與程式的其他部分相隔離的情況下進行測試。 > > —— 百度百科 http://baike.baidu.com/view/106237.htm ### 單元測試的好處 > 1. 它是一種驗證行為 > > 程式中的每一項功能都是測試來驗證它的正確性。 > > 2. 它是一種設計行為 > > 編寫單元測試將使我們從呼叫者觀察、思考。 特別是先寫測試(test-first),迫使我們把程式設計成易於呼叫和可測試的,有利於程式的解耦和模組化。 > > 3. 它是一種編寫文件的行為 > > 單元測試是一種無價的文件,它是展示函式或類如何使用的最佳文件。這份文件是可編譯、可執行的,並且它保持最新,永遠與程式碼同步。 > > 4. 它具有迴歸性 > > 自動化的單元測試避免了程式碼出現迴歸,編寫完成之後,可以隨時隨地的快速執行測試。 > > 5. 高效 > > 自動化的單元測試節省了開發上除錯BUG的時間,絕大多數BUG可以通過單元測試測試出來,並且可以減少測試人員的測試時間。有時候通過寫單元測試能夠更好的完善自己程式的邏輯,讓程式變得更加美好。 > > —— 單元測試的優點 http://jingyan.baidu.com/article/d713063522ab4e13fdf47533.html ### 單元測試的原則 > - 可重複執行的 > - 持續長期有效,並且返回一致的結果 > - 在記憶體中執行,沒有外部依賴元件(比如說真實的資料庫,真實的檔案儲存等) > - 快速返回結果 > - 一個測試方法只測試一個問題 ## .NET 中的測試框架 現在比較流行的測試框架包括微軟的 MS Test(VS Test)、NUnit、XUnit ### MS Test VS單元測試的主要類:Assert、StringAssert、CollectionAssert,具體可參照 [MSDN](https://msdn.microsoft.com/zh-cn/library/Microsoft.VisualStudio.TestTools.UnitTesting.aspx)介紹 有些時候我們需要對測試的方法用到的資料或配置進行初始化,有幾個特殊的測試方法。 如果需要針對測試中的所有虛擬使用者迭代僅執行一次初始化操作,請使用 `TestInitializeAttribute`。 初始化方法的執行順序如下: 1. 用 `AssemblyInitializeAttribute` 標記的方法。 2. 用 `ClassInitializeAttribute` 特性標記的方法。 3. 用 `TestInitializeAttribute` 特性標記的方法。 4. 用 `TestMethodAttribute` 特性標記的方法。 使用 VS Test 的時候,首先我們需要標記測試方法所在類 `TestClass`,測試方法標記為 `TestMethod` ### NUnit NUnit 測試框架使用方法與 MS Test 類似 有一些是 NUnit 中的,但是MS Test框架中是沒有的: `Assert.IsNaN`/`Assert.IsEmpty`/`Assert.IsNotEmpty`/`Assert.Greater`/`Assert.GreaterOrEqual` 等 想要同時使用 VS Test 和 NUnit 的話可以使用巨集來區分不同的測試框架,例如: ``` csharp #if !NUNIT using Microsoft.VisualStudio.TestTools.UnitTesting; using Category = Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute; #else using NUnit.Framework; using TestClass = NUnit.Framework.TestFixtureAttribute; using TestMethod = NUnit.Framework.TestAttribute; using TestInitialize = NUnit.Framework.SetUpAttribute; using TestCleanup = NUnit.Framework.TearDownAttribute; using TestContext = System.Object; using ClassCleanup = NUnit.Framework.TestFixtureTearDownAttribute; using ClassInitialize = NUnit.Framework.TestFixtureSetUpAttribute; #endif ``` 從上面可以看得出來 nunit 很多東西和 vs test 是很類似的,宣告測試類,測試方法,初始化方法等 ### XUnit XUnit 是另一個測試框架,個人覺得 XUnit 測試更加簡潔一些,初始化和釋放資源不需要標記單獨的方法,初始化直接放在構造方法裡,資源釋放實現 `IDisposable` 介面,在 `Dispose` 方法中進行測試的清理工作即可,相比 ms test(vs test)和 NUnit,我覺得 Xunit 更方便一些,並且對於 `Assert` ,xunit 更簡潔,例如: 在 ms test 中的 `Assert.IsNull(null);`/`Assert.IsTrue(1 == 1);` 在 xunit 中則是 `Assert.Null(null);`/`Assert.True(1 == 1);`,雖然看上去差不多,但是寫的多了就會覺得 xunit 更簡潔一些。 xunit 不需要對測試方法所在型別標記 `TestClass` ,只需要在測試方法上標記 `Fact` 或者使用資料驅動的 `Theory` ## XUnit 的基本使用 使用 XUnit 來寫測試方法可以使得測試程式碼更為簡潔,更加簡單,推薦使用 xunit 來測試自己的程式碼 測試示例: ``` csharp public class ResultModelTest { [Fact] public void SuccessTest() { var result = ResultModel.Success(); Assert.Null(result.ErrorMsg); Assert.Equal(ResultStatus.Success, result.Status); } [Theory] [InlineData(ResultStatus.Unauthorized)] [InlineData(ResultStatus.NoPermission)] [InlineData(ResultStatus.RequestError)] [InlineData(ResultStatus.NotImplemented)] [InlineData(ResultStatus.ResourceNotFound)] [InlineData(ResultStatus.RequestTimeout)] public void FailTest(ResultStatus resultStatus) { var result = ResultModel.Fail("test error", resultStatus); Assert.Equal(resultStatus, result.Status); } } ``` 最基本的測試,使用 `Fact` 標記測試方法,使用 `Assert` 來斷言自己對結果的預期 可以使用 `Theory` 來自己指定一批資料來進行測試,來實現測試資料驅動測試,簡單的資料可以通過 `InlineData` 直接指定,也可以使用 `MemberData` 來指定一個方法來返回用於測試的資料,也可以自定義一個繼承於 `DataAttribute` 的 Data Provider ## More 我覺得在我們開發過程中測試是非常重要的一部分,高質量專案的一個重要指標就是測試覆蓋率,,一個高質量的開源專案一定是有比較完善的測試專案的,所以對於測試非常有必要了解一下,並將它整合到自己的專案中持續保證專案的高質量,同時完善的測試對於專案重構也是非常有好處的,能夠很大程度上檢測是否有發生一些破壞性的變更。 總而言之,開始寫單元測試吧,為成為一個優秀的工程師而努力~~ ## Reference - [MSDN - Microsoft.VisualStudio.TestTools.UnitTesting](https://msdn.microsoft.com/zh-cn/library/Microsoft.VisualStudio.TestTools.UnitTesting.aspx) - [單元測試之道](http://www.cnblogs.com/Wddpct/p/5891222.html) - [VS2012 Unit Test 個人學習彙總(含目錄)](http://www.cnblogs.com/FreeDong/p/3352939.html) - [單元測試的優點](http://jingyan.baidu.com/article/d713063522ab4e13fdf47533.html) - [對比MS Test與NUnit Test框架](http://www.cnblogs.com/ColdJokeLife/p/3158812.html) -
- -