C#,單元測試入門

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

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

一、什麼叫單元測試(unit testing)?

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

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

二、爲什麼要進行單元測試。

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

三、誰做這一工作?

答案是:程序員自己,因爲程序員才明白自己寫的code,才知道要達到的效果。

四、什麼時候做?

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

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

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

C#,單元測試入門

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

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

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

複製代碼

3、 新建一個單元測試項目。名稱叫: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]
}
}
複製代碼

4、 打開“測試資源管理器”,在“測試”->窗口->測試資源管理器

C#,單元測試入門

可以看到目前還沒有測試項目。

C#,單元測試入門

現在去生成測試項目。

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

C#,單元測試入門

,在上面右擊。選“運行選定測試”,

C#,單元測試入門

可以看到前面多了一個通過標記。表示測試通過。
C#,單元測試入門

如果未通過。是個紅色的X,我們現在再寫一個未通過的方法。

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

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

    }

複製代碼

C#,單元測試入門

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

C#,單元測試入門

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

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

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

B、 還可以提示單元測試的結果。

C、 還可以提示源代碼版本管理器,提交及修改的情況。

C#,單元測試入門

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

C#,單元測試入門

六、現在說說單元測試裏Assert這個類。

(一)、Assert類的使用

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

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

3、Assert在測試方法中,可以調用任意數量的Assert類方法,如Assert.AreEqual()方法。Assert類有很多方法可供選擇,其中許多方法具有多個重載。

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

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

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

7、AssertInconclusiveException只要測試生成的結果是Inconclusive,就會引發 AssertInconclusiveException。通常,向仍在處理的測試添加Assert.Inconclusive來指明該測試尚未準備好, 不能運行。

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

1、 AreEqual:方法被重載了N多次,主要功能是判斷兩個值是否相等;如果兩個值不相等,則測試失敗。
2、 AreNotEqual:方法被重載了N多次,主要功能是判斷兩個值是否不相等;如果兩個值相等,則測試失敗。
3、 AreNotSame:引用的對象是否不相同;如果兩個輸入內容引用相同的對象,則測試失敗.
4、 AreSame:引用的對象是否相同;如果兩個輸入內容引用不相同的對象,則測試失敗
5、 Fail:斷言失敗。

6、 Inconclusive:表示無法證明爲 true 或 false 的測試結果
7、 IsFalse:指定的條件是否爲 false;如果該條件爲 true,則測試失敗。
8、 IsTrue:指定的條件是否爲 true;如果該條件爲 false,則測試失敗
9、 IsInstanceofType:測試指定的對象是否爲所需類型的實例;如果所需的實例不在該對象的繼承層次結構中,則測試失

10、 IsNotInstanceofType: 測試指定的對象是否爲所需類型的實例;如果所需的實例在該對象的繼承層次結構中,則測試失敗
11、 IsNull:測試指定的對象是否爲非空
12、 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都可以直接使用框架,而不需要自己去寫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章