C#,單元測試入門

https://www.cnblogs.com/KevinMO/articles/5657747.html
https://blog.csdn.net/u013244192/article/details/70821366
https://www.jianshu.com/p/7984955720e2
http://www.javashuo.com/article/p-pgbbwlpp-cr.html
https://www.cnblogs.com/qixuejia/p/5979827.html
https://docs.microsoft.com/en-us/visualstudio/test/unit-test-basics?view=vs-2015html

C#,單元測試入門(如下內容可能來自網絡)程序員

1、什麼叫單元測試(unit testing)?數據庫

是指對軟件中的最小可測試單元進行檢查和驗證。對於單元測試中單元的含義,通常來講,要根據實際狀況去斷定其具體含義,如C語言中單元指一個函 數,Java裏單元指一個類,圖形化的軟件中能夠指一個窗口或一個菜單等。總的來講,單元就是人爲規定的最小的被測功能模塊。單元測試是在軟件開發過程當中 要進行的最低級別的測試活動,軟件的獨立單元將在與程序的其餘部分相隔離的狀況下進行測試。編程

C#中,一個方法,一個類,一個窗口的測試。即單元測試。markdown

2、爲何要進行單元測試。網絡

爲了程序的正確性,儘早的發現程序的BUG,便於後期的開發及調試,維護。框架

3、誰作這一工做?ide

答案是:程序員本身,由於程序員才明白本身寫的code,才知道要達到的效果。函數

4、何時作?單元測試

單元測試越早越好,早到什麼程度?極限編程(Extreme Programming,或簡稱XP)講究TDD,即測試驅動開發,先編寫測試代碼,再進行開發。在實際的工做中,能夠沒必要過度強調先什麼後什麼,重要的是高效和感受溫馨。從經驗來看,先編寫產品函數的框架,而後編寫測試函數,針對產品函數的功能編寫測試用例,而後編寫產品函數的代碼,每寫一個功能點都運行測試,隨時補充測試用例。所謂先編寫產品函數的框架,是指先編寫函數空的實現,有返回值的直接返回一個合適值,編譯經過後再編寫測試代碼,這時,函數名、參數表、返回類型都應該肯定下來了,所編寫的測試代碼之後需修改的可能性比較小。

5、C#項目測試DEMO, 本demo用VS2015寫。

一、 新建一個控制檯應用。名稱叫:UnitTestDemo

C#,單元測試入門

二、 寫一個待測試的方法。

複製代碼
public class Program
{
static void Main(string[] args)
{
}

public static int Add(int pNum1,int pNum2)
    {
        return pNum1 + pNum2;
    }
}

複製代碼

三、 新建一個單元測試項目。名稱叫:UnitTestDemoTest

C#,單元測試入門

修改類名,及方法名。UnitTest1重命名爲ProgramTest,方法名:TestMethod1改成:AddTest。

這裏說明一下,方法面上面的特性:[TestMethod]這是必須的。告訴編譯器這是一個測試法式。

寫代碼。調用要測試的方法。

複製代碼
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using UnitTestDemo;

namespace UnitTestDemoTest
{
[TestClass]
public class ProgramTest
{
[TestMethod]
public void AddTest()
{
int a = 100;
int b = 10;
Assert.AreEqual(Program.Add(a, b), 110);
}
[TestMethod]
}
}
複製代碼

四、 打開「測試資源管理器」,在「測試」->窗口->測試資源管理器

C#,單元測試入門

能夠看到目前尚未測試項目。

C#,單元測試入門

如今去生成測試項目。

再回來看。是否是多了一個測試

C#,單元測試入門

,在上面右擊。選「運行選定測試」,

C#,單元測試入門

能夠看到前面多了一個經過標記。表示測試經過。
C#,單元測試入門

若是未經過。是個紅色的X,咱們如今再寫一個未經過的方法。

注意方法的特性必定要加[TestMethod],而後生成應用,再去運行測試。

複製代碼
public void AddTest2()
{
int a = 100;
int b = 10;
Assert.AreEqual(Program.Add(a, b), 50);

}

複製代碼

C#,單元測試入門

五、 回到主項目。看方法提示行。上面有標測測試經過。

C#,單元測試入門

在方法上面有一個清楚的提示。

這裏說一下VS的強大功能。這個提示很好用。

A、 能夠提示方法的引用數量,並快速定位,

B、 還能夠提示單元測試的結果。

C、 還能夠提示源代碼版本管理器,提交及修改的狀況。

C#,單元測試入門

六、 以上是手工創建測試項目的。還有一種快捷的方法創建測試項目。在要測試的方法行,右擊。選擇建立單元測試。可彈出創建單元測試對話框。

C#,單元測試入門

6、如今說說單元測試裏Assert這個類。

(一)、Assert類的使用

一、Assert類所在的命名空間爲Microsoft.VisualStudio.TestTools.UnitTesting 在工程文件中只要引用Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll就可使用 了。

二、使用Assert類能夠對特定功能進行驗證,單元測試方法執行開發代碼中的方法代碼,但只有包含Assert語句時才能報告代碼行爲方面的內容。

三、Assert在測試方法中,能夠調用任意數量的Assert類方法,如Assert.AreEqual()方法。Assert類有不少方法可供選擇,其中許多方法具備多個重載。

四、使用CollectionAssert類可比較對象集合,也能夠驗證一個或多個集合的狀態。

五、使用StringAssert類能夠對字符串進行比較。此類包含各類有用的方法。如:StringAssert.Contains、StringAssert.Matches和StringAssert.StartWith。

六、AssertFailedException只要測試失敗,就會引起AssertFailedException異常。若是測試超時,引起意外的異常,或包含生成了Failed結果的Assert語句,則測試失敗。

七、AssertInconclusiveException只要測試生成的結果是Inconclusive,就會引起 AssertInconclusiveException。一般,向仍在處理的測試添加Assert.Inconclusive來指明該測試還沒有準備好, 不能運行。

(二)、Assert類主要的靜態成員

一、 AreEqual:方法被重載了N屢次,主要功能是判斷兩個值是否相等;若是兩個值不相等,則測試失敗。
二、 AreNotEqual:方法被重載了N屢次,主要功能是判斷兩個值是否不相等;若是兩個值相等,則測試失敗。
三、 AreNotSame:引用的對象是否不相同;若是兩個輸入內容引用相同的對象,則測試失敗.
四、 AreSame:引用的對象是否相同;若是兩個輸入內容引用不相同的對象,則測試失敗
五、 Fail:斷言失敗。

六、 Inconclusive:表示沒法證實爲 true 或 false 的測試結果
七、 IsFalse:指定的條件是否爲 false;若是該條件爲 true,則測試失敗。
八、 IsTrue:指定的條件是否爲 true;若是該條件爲 false,則測試失敗
九、 IsInstanceofType:測試指定的對象是否爲所需類型的實例;若是所需的實例不在該對象的繼承層次結構中,則測試失

十、 IsNotInstanceofType: 測試指定的對象是否爲所需類型的實例;若是所需的實例在該對象的繼承層次結構中,則測試失敗
十一、 IsNull:測試指定的對象是否爲非空
十二、 IsNotNull:測試指定的對象是否爲非空

  1. 單元測試中不得不說的知識點
    (1)斷言Assertion
    要驗證代碼的行爲是否與指望一致時,咱們須要使用斷言來判斷某個語句爲真或爲假,以及某些結果值與指望值是否相等,如IsTrue()、IsFalse()、AreEqual()等。

Assert.AreEqual(expected, actual [, string message]);
其中前兩個參數很好理解,分別爲指望值和實際值,最後一個可選參數是發生錯誤時報告的消息。若是不提供的話,出錯後會看到這樣的error message:Assert.AreEqual failed. Expected: xx. Actual: yy.。若是你的那個單元測試函數中有不少Assert.AreEqual的話,你就不清楚到底是在哪一個Assertion出錯的,而當你對每一個Assertion放上相應的message的話,出錯時就能夠一眼看出具體出錯的Assertion。
另外,在用斷言進行浮點數的比較時還須要提供另一個參數tolerance。
有時候每一個test裏咱們都須要進行一系列相同或者相似的斷言,那麼咱們能夠嘗試編寫自定義的斷言,這樣測試的時候使用這個自定義的斷言便可。

(2)test 組成
從上面的例子能夠看到,test project與普通project的區別就是在class和method上面增長了一個屬性。在不一樣的框架下這些屬性仍是不同的,好比說咱們上面用到的VS裏自帶的test框架,使用的是[TestClass]和[TestMethod],而你們最經常使用的NUint框架則使用的是[TestFixture]和[Test]。
另外,還有幾個attribute在實際項目中咱們也會常常用到,那就是[SetUp]、[TearDown]、[TestFixtureSetUp]和[TestFixtureTearDown]。它們用來在調用test以前設置測試環境和在test以後釋放資源。前兩個是per-method,即每一個用[Test]修飾的方法在運行先後都會調用[SetUp]和[TearDown];然後兩個則是per-class的,即用於[TestFixture]修飾的類的先後。

(3)對於異常的測試
對於預期的異常,只要在測試方法上添加[ExpectedException(typeof(YourExpectedExcetion))]屬性便可。可是須要注意的是,一旦這個方法指望的異常拋出了,測試方法中剩餘的代碼就會被跳過。
因此NUint裏面還有一種方式來驗證異常,即Assert.Throws<ExpectedException>(() => methodToTest());,這樣就能夠在一個test method裏面驗證多個拋出異常的狀況了。

(4)使用mock對象
單元測試的目標是一次只驗證一個方法或一個類,可是若是這個方法依賴一些其餘難以操控的東西,好比網絡、數據庫等。這時咱們就要使用mock對象,使得在運行unit test的時候使用的那些難以操控的東西其實是咱們mock的對象,而咱們mock的對象則能夠按照咱們的意願返回一些值用於測試。

好比說,咱們在某個函數中須要利用HttpClient經過SendAsync方法從某個EndPoint獲取數據進行處理。可是在local測試的時候不必定可以連上那個EndPoint,或者不能保證那個EndPoint會返回什麼東西。因此咱們能夠寫mock一個ResponseHandler,這樣咱們就能夠把mock的返回結果放進httpClient中傳給須要測試的模塊,這樣就能夠測試該模塊內後續部分的處理了。

實際上,.NET中如今不少mock對象的框架供選擇(參見http://www.mockobjects.org ),不少經常使用的mock均可以直接使用框架,而不須要本身去寫。

相關文章
相關標籤/搜索