單元測試不是軟件開發的新概念,在1970年就一直存在,屢屢被證實是最理想的方法之一。html
本系列將分紅3節:框架
本節索引:函數
單元測試幾乎老是基於框架來寫的,由於框架能夠爲咱們提供統一的API來管理測試。單元測試
經常使用的框架有Unit Test(MS Test),NUnit(開源)測試
定義編碼
單元測試是一段代碼調用另外一段代碼,隨後檢驗一些假設的正確性。(單元指的是一個方法或函數)spa
集成測試是指把2個或多個互相依賴的軟件模塊做爲一組進行測試。設計
優秀的單元測試準則code
對於TDD確切的含義,有不少不一樣的觀點,有人以爲就是測試優先的開發,有人以爲意味着大量的測試,有人以爲是一種設計方法。
TDD的流程:
寫測試 寫代碼 重構 寫下一個測試
它顯示了TDD是增量性質的,每次一小步,最終完成高質量的軟件。(重構能夠在完成每一個測試後進行,也能夠在完成幾個測試後進行。重構是很是有價值意義的。)
TDD的優勢:
全部的測試框架都共享相同的核心特性:Test Declaration, Test Execution, and Assertions.
在.Net中通常使用特性標籤來添加額外的信息,下面就是MS Test和NUnit在特性標籤上不一樣的地方。
MS Test Attribute | NUnit Attribute | 用途 |
[TestClass] | [TestFixture] | 定義一個測試類,裏面能夠包含不少測試函數和初始化、銷燬函數(如下全部標籤和其餘斷言)。 |
[TestMethod] | [Test] | 定義一個獨立的測試函數。 |
[ClassInitialize] | [TestFixtureSetUp] | 定義一個測試類初始化函數,每當運行測試類中的一個或多個測試函數時,這個函數將會在測試函數被調用前被調用一次(在第一個測試函數運行前會被調用)。 |
[ClassCleanup] | [TestFixtureTearDown] | 定義一個測試類銷燬函數,每當測試類中的選中的測試函數所有運行結束後運行(在最後一個測試函數運行結束後運行)。 |
[TestInitialize] | [SetUp] | 定義測試函數初始化函數,每一個測試函數運行前都會被調用一次。 |
[TestCleanup] | [TearDown] | 定義測試函數銷燬函數,每一個測試函數執行完後都會被調用一次。 |
[AssemblyInitialize] | -- | 定義測試Assembly初始化函數,每當這個Assembly中的有測試函數被運行前,會被調用一次(在Assembly中第一個測試函數運行前會被調用)。 |
[AssemblyCleanup] | -- | 定義測試Assembly銷燬函數,當Assembly中全部測試函數運行結束後,運行一次。(在Assembly中全部測試函數運行結束後被調用) |
[DescriptionAttribute] | [Category] | 定義標識分組。 |
安裝
對於MS Test,只要安裝VS則會自動安裝。在工具欄==測試==窗口==測試資源管理器打開。
對於NUnit,點擊連接,下載安裝便可。
編碼
[TestClass] public class BlogTests { public DbContext Db { get; set; } /// <summary> /// 每一個測試方法執行前都會執行 /// </summary> [TestInitialize] public void Init() { //1 配置對象 Db = new DbContext(); } [TestMethod] public void TestAdd() { var blog = new Blog { Title = "單元測試的藝術", Content = "單元測試是一門藝術" }; //2 操做對象 Db.Add(blog); //3 斷言結果 Assert.IsTrue(blog.Id > 0); } /// <summary> /// 每一個測試方法執行後都會執行 /// </summary> [TestCleanup] public void Clean() { Db = null; } }
異常的測試
有時候,測試裏面上須要拋出異常,這是業務上的正確性。在單元測試裏,也有對應特性用來實現。如
[ExpectedException(typeof(OutOfMemoryException), AllowDerivedTypes = true)]//默認異常的子類也會不經過測試的 [TestMethod] public void TestAdd() { var blog = new Blog { Title = "單元測試的藝術", Content = "單元測試是一門藝術" }; //2 操做對象 Db.Add(blog); throw new OutOfMemoryException(); //3 斷言結果 Assert.IsTrue(blog.Id > 0); }
忽略的測試
有時候,測試寫的有問題,代碼沒問題。咱們能夠暫時忽略該測試
[Ignore] [TestMethod] public void TestAdd() { var blog = new Blog { Title = "單元測試的藝術", Content = "單元測試是一門藝術" }; //2 操做對象 Db.Add(blog); throw new OutOfMemoryException(); //3 斷言結果 Assert.IsTrue(blog.Id > 0); }
對測試分組
當咱們只想測試某一類測試的時候,也有對應的特性
[TestCategory("change db")] [TestMethod] public void TestAdd() { var blog = new Blog { Title = "單元測試的藝術", Content = "單元測試是一門藝術" }; //2 操做對象 Db.Add(blog); //3 斷言結果 Assert.IsTrue(blog.Id > 0); } [TestCategory("no change")] [TestMethod] public void TestRead() { //2 操做對象 var blogs = Db.GetBlogs(); //3 斷言結果 Assert.IsTrue(blogs.Length > 0); }
運行選定的測試便可
測試
SUT Kind | SUT |
項目 | 新建一個【被測項目】.Tests的測試項目 |
類 | 至少爲每一個被測試類新建一個【被測類名】Tests的類 |
方法 | 至少爲每一個方法名新建一個【方法名】【測試場景】【預期行爲】的方法 或者使用Test【方法名】的簡單命名 |
備註:SUT("system under test")表明被測系統,有些人喜歡CUT("code under test")。一般SUT。
本文做者:Never、C
本文連接:http://www.cnblogs.com/neverc/p/4742654.html