「不會寫單元測試的程式設計師不是合格的程式設計師,不寫單元測試的程式設計師不是優秀的工程師。」
—— 一隻想要成為一個優秀程式設計師的渣逼程序猿。
那麼問題來了,什麼是單元測試,如何做單元測試。
單元測試單元測試的定義按照維基百科上的說法,單元測試(Unit Testing)又稱為模塊測試, 是針對程序模塊(軟體設計的最小單位)來進行正確性檢驗的測試工作。程序單元是應用的最小可測試部件。在面向對象編程中,最小單元就是方法,包括基類、抽象類、或者派生類(子類)中的方法。按照通俗的理解,一個單元測試判斷某個特定場條件下某個特定方法的行為,如斐波那契數列算法,冒泡排序算法。
單元測試(unit testing),是指對軟體中的最小可測試單元進行檢查和驗證。對於單元測試中單元的含義,一般來說,要根據實際情況去判定其具體含義, 如C語言中單元指一個函數,Java裡單元指一個類,圖形化的軟體中可以指一個窗口或一個菜單等。總的來說,單元就是人為規定的最小的被測功能模塊。單元測試是在軟體開發過程中要進行的最低級別的測試活動,軟體的獨立單元將在與程序的其他部分相隔離的情況下進行測試。
—— 百度百科 http://baike.baidu.com/view/106237.htm
單元測試的好處它是一種驗證行為
程序中的每一項功能都是測試來驗證它的正確性。
它是一種設計行為
編寫單元測試將使我們從調用者觀察、思考。特別是先寫測試(test-first),迫使我們把程序設計成易於調用和可測試的,有利於程序的解耦和模塊化。
它是一種編寫文檔的行為
單元測試是一種無價的文檔,它是展示函數或類如何使用的最佳文檔。這份文檔是可編譯、可運行的,並且它保持最新,永遠與代碼同步。
它具有回歸性
自動化的單元測試避免了代碼出現回歸,編寫完成之後,可以隨時隨地的快速運行測試。
高效
自動化的單元測試節省了開發上調試BUG的時間,絕大多數BUG可以通過單元測試測試出來,並且可以減少測試人員的測試時間。有時候通過寫單元測試能夠更好的完善自己程序的邏輯,讓程序變得更加美好。
—— 單元測試的優點 http://jingyan.baidu.com/article/d713063522ab4e13fdf47533.html
單元測試的原則在內存中運行,沒有外部依賴組件(比如說真實的資料庫,真實的文件存儲等).NET 中的測試框架現在比較流行的測試框架包括微軟的 MS Test(VS Test)、NUnit、XUnit
MS TestVS單元測試的主要類:Assert、StringAssert、CollectionAssert,具體可參照 MSDN介紹
有些時候我們需要對測試的方法用到的數據或配置進行初始化,有幾個特殊的測試方法。
如果需要針對測試中的所有虛擬用戶迭代僅執行一次初始化操作,請使用 TestInitializeAttribute。
初始化方法的運行順序如下:
用 AssemblyInitializeAttribute 標記的方法。用 ClassInitializeAttribute 特性標記的方法。用 TestInitializeAttribute 特性標記的方法。用 TestMethodAttribute 特性標記的方法。使用 VS Test 的時候,首先我們需要標記測試方法所在類 TestClass,測試方法標記為 TestMethod
NUnitNUnit 測試框架使用方法與 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 是很類似的,聲明測試類,測試方法,初始化方法等
XUnitXUnit 是另一個測試框架,個人覺得 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 來測試自己的代碼
測試示例:
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我覺得在我們開發過程中測試是非常重要的一部分,高質量項目的一個重要指標就是測試覆蓋率,,一個高質量的開源項目一定是有比較完善的測試項目的,所以對於測試非常有必要了解一下,並將它集成到自己的項目中持續保證項目的高質量,同時完善的測試對於項目重構也是非常有好處的,能夠很大程度上檢測是否有發生一些破壞性的變更。
總而言之,開始寫單元測試吧,為成為一個優秀的工程師而努力~~
ReferenceMSDN - Microsoft.VisualStudio.TestTools.UnitTestingVS2012 Unit Test 個人學習匯總(含目錄)https://stackoverflow.com/questions/261139/nunit-vs-mbunit-vs-mstest-vs-xunit-nethttps://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-with-dotnet-test