「不會寫單元測試的程序員不是合格的程序員,不寫單元測試的程序員不是優秀的工程師。」html
—— 一隻想要成爲一個優秀程序員的渣逼程序猿。程序員
那麼問題來了,什麼是單元測試,如何作單元測試。算法
按照維基百科上的說法,單元測試(Unit Testing)又稱爲模塊測試, 是針對程序模塊(軟件設計的最小單位)來進行正確性檢驗的測試工做。 程序單元是應用的最小可測試部件。在面向對象編程中,最小單元就是方法,包括基類、抽象類、或者派生類(子類)中的方法。 按照通俗的理解,一個單元測試判斷某個特定場條件下某個特定方法的行爲,如斐波那契數列算法,冒泡排序算法。數據庫
單元測試(unit testing),是指對軟件中的最小可測試單元進行檢查和驗證。 對於單元測試中單元的含義,通常來講,要根據實際狀況去斷定其具體含義, 如C語言中單元指一個函數,Java裏單元指一個類,圖形化的軟件中能夠指一個窗口或一個菜單等。 總的來講,單元就是人爲規定的最小的被測功能模塊。 單元測試是在軟件開發過程當中要進行的最低級別的測試活動,軟件的獨立單元將在與程序的其餘部分相隔離的狀況下進行測試。編程
—— 百度百科 http://baike.baidu.com/view/106237.htm框架
它是一種驗證行爲ide
程序中的每一項功能都是測試來驗證它的正確性。模塊化
它是一種設計行爲函數
編寫單元測試將使咱們從調用者觀察、思考。 特別是先寫測試(test-first),迫使咱們把程序設計成易於調用和可測試的,有利於程序的解耦和模塊化。單元測試
它是一種編寫文檔的行爲
單元測試是一種無價的文檔,它是展現函數或類如何使用的最佳文檔。這份文檔是可編譯、可運行的,而且它保持最新,永遠與代碼同步。
它具備迴歸性
自動化的單元測試避免了代碼出現迴歸,編寫完成以後,能夠隨時隨地的快速運行測試。
高效
自動化的單元測試節省了開發上調試BUG的時間,絕大多數BUG能夠經過單元測試測試出來,而且能夠減小測試人員的測試時間。有時候經過寫單元測試可以更好的完善本身程序的邏輯,讓程序變得更加美好。
—— 單元測試的優勢 http://jingyan.baidu.com/article/d713063522ab4e13fdf47533.html
- 可重複運行的
- 持續長期有效,而且返回一致的結果
- 在內存中運行,沒有外部依賴組件(好比說真實的數據庫,真實的文件存儲等)
- 快速返回結果
- 一個測試方法只測試一個問題
如今比較流行的測試框架包括微軟的 MS Test(VS Test)、NUnit、XUnit
VS單元測試的主要類:Assert、StringAssert、CollectionAssert,具體可參照 MSDN介紹
有些時候咱們須要對測試的方法用到的數據或配置進行初始化,有幾個特殊的測試方法。
若是須要針對測試中的全部虛擬用戶迭代僅執行一次初始化操做,請使用 TestInitializeAttribute
。
初始化方法的運行順序以下:
AssemblyInitializeAttribute
標記的方法。ClassInitializeAttribute
特性標記的方法。TestInitializeAttribute
特性標記的方法。TestMethodAttribute
特性標記的方法。使用 VS Test 的時候,首先咱們須要標記測試方法所在類 TestClass
,測試方法標記爲 TestMethod
NUnit 測試框架使用方法與 MS Test 相似
有一些是 NUnit 中的,可是MS Test框架中是沒有的:
Assert.IsNaN
/Assert.IsEmpty
/Assert.IsNotEmpty
/Assert.Greater
/Assert.GreaterOrEqual
等
想要同時使用 VS Test 和 NUnit 的話可使用宏來區分不一樣的測試框架,例如:
#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 測試更加簡潔一些,初始化和釋放資源不須要標記單獨的方法,初始化直接放在構造方法裏,資源釋放實現 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 來測試本身的代碼
測試示例:
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
我以爲在咱們開發過程當中測試是很是重要的一部分,高質量項目的一個重要指標就是測試覆蓋率,,一個高質量的開源項目必定是有比較完善的測試項目的,因此對於測試很是有必要了解一下,並將它集成到本身的項目中持續保證項目的高質量,同時完善的測試對於項目重構也是很是有好處的,可以很大程度上檢測是否有發生一些破壞性的變動。
總而言之,開始寫單元測試吧,爲成爲一個優秀的工程師而努力~~