摘要:本教程不會介紹單元測試的基本理論知識,也不會和大家討論在實際項目中是否需要寫單元測試代碼的問題。但是如果你此時想使用VS中的單元測試的工具來測試某個方法是否正確,可你又從來沒真正實踐過,那么本教程將帶你一步一步使用VS2010集成的Unit Test進行斷言(Assert)式驗證數據的正確性,及代碼覆蓋率的查看。
關鍵詞:Unit Test、單元測試、代碼覆蓋率、Assert、Twifly
正文:
在本入門教程中我們假設來測試一個簡單的加法運算方法是否正確。該方法能夠接受任意個參數,參數類型可以是整型、字符型、浮點型,對於其他復雜類型我們這里暫時忽略。既然作為入門教程,那么下面我們按照詳細的步驟開始。
1、 先創建一個空白解決方案(文件—>新建—>項目—>已安裝的模版—>其他項目類型—>Visual Studio解決方案-->空白解決方案)命名為TestUnit。
2、 在新創建的解決方案(TestUnit)鼠標右鍵,選擇添加—>新建項目—>控制台應用程序。
如下圖所示:
3、 在控制台應用程序中,我們添加一個Operation類。添加一個簡單的Add方法,該方法能對一個dynamic類型的列表的各項求和,簡單地,我們這里假設傳入的類型只可能是int、double、string類型,所以不對其他類型做異常捕捉。代碼如下:
public class Operation
{
public static dynamic Add(List<dynamic> numbers)
{
dynamic sum = 0;
foreach (var n in numbers)
{
var s = n;
if (s is string)
{
s = -Convert.ToDouble(n); //我們這里故意在轉換前加了一個取反運算
}
sum += s;
}
return sum;
}
}
4、 現在我們來對Add方法做下單元測試。將光標放在Add方法名上,然后右鍵選擇“創建單元測試(C)…”,如下圖所示:
5、這時會彈出“創建單元測試”窗口,如下圖所示,一般情況下直接點擊確定即可。

6、如果直接點擊確定按鈕,系統將按照默認的命名規則(直接加Test后綴)生成測試文件。當然你也可以點擊上圖中的“設置…”按鈕,在彈出的“測試生成設置”中進行規則修改。如下圖所示:
7、因為這是我們第一次創建單元測試項目,所以在輸出選項中,我們選擇默認的“創建新的Visual C# 測試項目”。在單擊“確定”按鈕后,要求我們填寫測試項目的名稱,名稱自己隨便,這里我們就用默認的TestProject1。點擊“創建”即可。如果我們以后還對另一個方法進行單元測試,我們就可以在輸出項目中直接選擇“TestProject1”了,而不比再創建新的測試項目。如下圖所示:
8、 這時,在解決方案下面,系統自動為我們創建了TestProject1測試項目和Solution Items(解決方案項)文件夾。

9、雙擊TestProject1測試項目下的OperationTest.cs文件,我們看一下系統為我們自動生成的測試代碼。會發現主要有一下幾點:
? 在代碼文件頂部增加了一個:using Microsoft.VisualStudio.TestTools.UnitTesting;
? 在生成的OperationTest類上標記了[TestClass()],即使用了TestClassAttribute
? 對測試類的方法AddTest標記了[TestMethod()]
? 在測試類OperationTest中,定義了一個類型為TestContext的變量testContextInstance
? 附加測試特性
10、我們現在要做的就是要對AddTest方法編寫測試代碼,一般情況下只需要簡單地將TODO部分填寫完整,將默認的代碼:

改成如下測試代碼進行第一組測試:
/// <summary>
///Add 的測試
///</summary>
[TestMethod()]
public void AddTest()
{
List<dynamic> numbers = new List<dynamic>() { 1, 2, 3, 4, 5 };
dynamic expected = 15;
dynamic actual;
actual = Operation.Add(numbers);
Assert.AreEqual(expected, actual);
}
這個方法就是對整型1、2、3、4、5累加進行測試,我們期望的結果是15。Assert類的AreEqual方法用於驗證實際結果和期望值是否相等。Assert斷言類包含很多方法用於比較,在測試方法中,可以調用任意數量的 Assert 類方法,如 Assert.AreEqual()。Assert 類有很多方法可供選擇,其中許多方法具有若干重載。詳情可以參考MSDN的Assert類。
默認生成的代碼中Assert.Inconclusive 語句用於指示該測試尚未准備好,不能運行(不能確定結果是否正確),所以當我們寫好測試代碼后,Assert.Inconclusive語句就可以刪除了。
11、運行單元測試。打開測試視圖(測試-->窗口-->測試視圖),測試視圖中會以列表的方式顯示測試方法。右鍵菜單選擇“運行選定內容”即可執行對該方法的測試,如下圖所示:

VS2010接到測試的指令后,在測試完成后會自動彈出“測試結果”窗口,結果顯示通過,表示測試結果值和預期結果相同。

12、上面一組單元測試(整型)結果是通過,但是我們知道對字符串操作是故意留有錯誤,但是實際過程中,那段代碼並沒有執行。所以我們還要對字符格式的數字進行測試,當然還有浮點型、負數等等,這些可以都單獨測試,也可以一起測試。把測試代碼改成:
/// <summary>
///Add 的測試
///</summary>
[TestMethod()]
public void AddTest()
{
List<dynamic> numbers = new List<dynamic>() { 1, 2, 3, 4, 5 };
dynamic expected = 15;
dynamic actual;
actual = Operation.Add(numbers);
Assert.AreEqual(expected, actual);
List<dynamic> numbers2 = new List<dynamic>() { "1", "2", "3", "4" };
dynamic expected2 = 10;
dynamic actual2;
actual2 = Operation.Add(numbers2);
Assert.AreEqual(expected2, actual2);
List<dynamic> numbers3 = new List<dynamic>() { "1", 2.5, 3, "4.5", 5, 6 };
dynamic expected3 = 22;
dynamic actual3;
actual3 = Operation.Add(numbers3);
Assert.AreEqual(expected3, actual3);
}
我們再進行一次測試(第二組測試)。每次測試代碼修改后,會提示我們刷新更新,直接點擊刷新按鈕即可。

看看測試結果如何:

這個時候我們發現測試顯示未通過,右鍵菜單單擊“查看測試結果詳細信息”,如下圖所示:


13、錯誤消息提示期望指為10,但實際結果為-10,我們很容易知道是下面組數據出了問題:
List<dynamic> numbers2 = new List<dynamic>() { "1", "2", "3", "4" };
找到代碼:s = -Convert.ToDouble(n); //我們這里故意在轉換前加了一個取反運算,把前面的取反運算符去掉,改成:s = Convert.ToDouble(n); 再進行一次測試,測試結果會按預期的方式顯示為通過。
14、調試單元測試。上面能一下子就把錯誤修改,是因為錯誤是我們故意設置的。在實際開發中,找錯誤也許並不明顯,通常是需要調試后才容易找到。調試單元測試和平時斷點測試是一樣的,在需要的地方設置斷點后,在測試視圖中右鍵選擇“調試選定內容”,接下來就是大家所熟悉的斷點調試步驟了。如下圖所示:

15、查看代碼覆蓋率。單元測試的編寫,涉及到很多要求,但是最基本的就是需要編寫多組數據對各個分支代碼都至少需要執行一遍。如我們前面第一組直接測試整型相加(1、2、3、4、5)測試結果15為通過,沒找到潛在的錯誤,是因為有些代碼沒被執行。查看代碼覆蓋率就能幫助你檢測測試數據是否會覆蓋所有分支代碼。
如下圖所示,右鍵選擇“覆蓋率結果”,可以查看代碼覆蓋率。

第一組數據測試代碼覆蓋率:

第二組數據測試代碼覆蓋率:

16、代碼覆蓋率默認演示顯示說明:
顏色代碼 |
說明 |
淺藍色 |
指示在測試運行過程中執行了整個代碼行。 |
淺褐色 |
指示在測試運行過程中僅執行了代碼行的部分代碼塊。 |
紅棕色 |
指示在測試運行過程中未執行此行。 |
當然這些默認顏色可以在工具菜單下的選項中進行設置,如下圖所示:

17、如果在查看代碼覆蓋率中出現如下提示,則我們需要簡單配置一下

在“測試視圖”中,找到Solution Items(解決方案項)文件夾下的Local.testsettings,雙擊打開“測試設置”窗口,選擇“數據和診斷”,將代碼覆蓋率設置為啟用,然后點擊“配置”對代碼覆蓋率進行配置,如下圖所示:

在我們的控制台應用程序前打勾,然后點擊確定按鈕

最后對“測試設置”點擊“應用”按鈕完成代碼覆蓋率的配置。重新運行測試,就可以查看代碼覆蓋率了。
到這里已經完成了如何簡單使用VS2010自帶的單元測試工具進行斷言式Assert條件測試,當然以后我們還可能接觸到CollectionAssert類來比較集合對象、StringAssert 類來對字符串進行比較等等,在后面的教程中我們將接觸到。
最后如果對本入門教程仍有疑問,可以參考MSND官方的教程文章。
MSDN官方參考:
演練:創建並運行單元測試
http://msdn.microsoft.com/zh-cn/library/ms182532.aspx
如何:創建和運行單元測試
http://msdn.microsoft.com/zh-cn/library/dd286656.aspx
單元測試分析
http://msdn.microsoft.com/zh-cn/library/ms182517.aspx
使用 Assert 類
http://msdn.microsoft.com/zh-cn/library/ms182530(v=vs.100).aspx
演練:運行測試並查看代碼覆蓋率