﻿# ASP.NET MVC 單元測試系列 (1)：新手上路 / 開始撰寫！

因為軟體測試越來越重要，而單元測試正是跨出軟體測試重要的第一步，不過軟體測試的學習之路卻異常艱辛，最主要的難處在於沒有人可以討論，不知道什麼是對？什麼是錯？判斷的依據在哪？哪個決定好？哪個決定壞？什麼才是最恰當的？千千萬萬個疑問不知道從何下手？所以我預計寫一系列與 ASP.NET MVC 單元測試的文章，一方面透過寫作的過程幫助自己釐清各種測試的觀念，另一方面也可以跟四面八方開發人員互動，期望能獲得最正確的觀念。

第一篇，不要給大家太多壓力，先看看 ASP.NET MVC 如何開始撰寫單元測試

[![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/d222b0559f4969979509-SNAGHTML124f26f0_thumb.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/ce96fdfad380179ca156-SNAGHTML124f26f0.png)

是的，在建立 ASP.NET MVC 2 Web 應用程式專案時，就直接把測試專案給建立起來吧

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/59bb0b4935c83d4f1d29-SNAGHTML125016ab.png)

建立完成後在 Visual Studio 2010 之中會出現 2 個專案，分別是預設的 **MvcApplication1** 專案，以及 **MvcApplication1.Test** 單元測試專案，如下圖示，在 **MvcApplication1.Test** 單元測試專案下已經有兩個寫好的測試類別(TestClass)與測試方法(TestMethod)，裡面有不少程式碼可以學習觀摩若看的懂是可以學到一些單元測試的幾個非常重要的觀念。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/0e790663007f751ed5f2-image_168.png)

我們先拿最沒營養 (最簡單的意思) 的 **HomeControllerTest.cs** 來說明，在這個測試方法中我們僅驗證執行完 ASP.NET MVC 的 Action 之後是否回傳的 **ViewData\["Message"\]** 是否為預期的字串！

 ![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/a4f94cb36f072faadc1e-image_169.png)

編號說明：

1.  每個「測試類別」都要套上 TestClass 屬性(Attribute)
2.  每個「測試方法」都要套上 TestMethod 屬性(Attribute)
3.  每個「測試方法」的標準程式結構之 1：**排列(Arrange)  
    **先安排要進行測試的資料，或準備要執行該測試所需的變數
4.  每個「測試方法」的標準程式結構之 2：**作用(Act)**  
    執行要被測試的方法，並取得執行的結果
5.  每個「測試方法」的標準程式結構之 3：**判斷提示(Assert)  
    **這部分負責用來判斷程式執行的結果是否符合預期！

備註：以上測試方法的三個步驟又稱為 **3A Pattern**

接著，該檔案的第二個 About() 測試方法如下，程式碼的結構完全一模一樣，還是套用 3A Pattern 進行開發，預設的判斷提示只有判斷 result 是不為 Null 而已 ( [Assert.IsNotNull](http://msdn.microsoft.com/zh-tw/library/microsoft.visualstudio.testtools.unittesting.assert.isnotnull.aspx) )，而我自己又多加上了個額外的判斷，判斷 Action 回傳時是不是沒有指定 ViewName，如果沒有指定 ViewName 就代表正確：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/d922b355723e739258db-image_170.png)

雖然在同一個測試方法中可以判斷多種不同的條件，但是不見得這樣就是好的，如果測試的需求簡單、明確，那麼是可以把一堆沒營養的判斷(Assert)寫在一起；如果要測試的東西不容易從程式碼一眼看穿，那麼就可以建議將不同的測試目的猜成不同的測試方法，也就是一個被測試的方法(Method)用多個測試方法(Test Method)來測試它。

測試程式寫完後最重要的 2 個工具列按鈕你一定要知道：

1\. **執行目前內容中的測試** ( 或這顆按鈕的右邊一顆是執行所有測試 )

 ![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/6a6972aca4068c77f182-image_171.png)

2\. **偵錯目前內容中的測試** ( 或這顆按鈕的右邊一顆是執行所有測試 )，可利用**單步執行**進行逐一偵錯！

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/b13a23eedae95348c6a3-image_172.png)

若執行全部測試即可看出所有測試的結果，如果全部都亮綠燈的話，那就恭喜你的單元測試全數通過！無論測試成功或失敗，都可以按下滑鼠右鍵進行檢視測試結果詳細資料。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/8fd72afa7510240f1610-image_173.png)

以下是我們修改了測試方法的程式內容（模擬需求變更的情況）

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/5bcb85a67f85f5b53ec9-image_174.png)

這時我們跑測試程式就會發現有紅燈亮起：（點圖可放大顯示）

[![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/e69387612d95a9385938-image_thumb_25.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/d29ef4b3c857080e541a-image_175.png)

查看詳細資料的畫面如下：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/64eacc3a8dc9117c47c0-image_176.png)

以上就是在 ASP.NET MVC 的世界裡最簡單的「單元測試」程式，疑問還很多，咱們慢慢來釐清問題，歡迎各位留言探討問題，如有謬誤之處敬請指教，謝謝。

**範例程式下載**

-   [MvcApplication1.zip](http://cid-ce50199d9432ea57.office.live.com/self.aspx/%e5%85%ac%e9%96%8b/ASP.NET%20MVC%20%e5%96%ae%e5%85%83%e6%b8%ac%e8%a9%a6%e7%b3%bb%e5%88%97/MvcApplication1.zip "http://cid-ce50199d9432ea57.office.live.com/self.aspx/%e5%85%ac%e9%96%8b/ASP.NET%20MVC%20%e5%96%ae%e5%85%83%e6%b8%ac%e8%a9%a6%e7%b3%bb%e5%88%97/MvcApplication1.zip")

**相關連結**

-   [與 Roy Osherove 探討單元測試的藝術 (心得筆記)](/post/2010/02/21/The-Art-of-Unit-Testing-with-Roy-Osherove-Notes.aspx)
-   [使用單元測試](http://msdn.microsoft.com/zh-tw/library/ms182515.aspx)
-   [單元測試 - 維基百科，自由的百科全書](http://zh.wikipedia.org/zh-tw/單元測試)
-   [\[VS2010 Online\]初窺ASP.NET MVC(6) - 單元測試(Unit Test)](https://dotblogs.com.tw/lolota/2010/03/28/14267)
-   [Assert 成員 (Microsoft.VisualStudio.TestTools.UnitTesting)](http://msdn.microsoft.com/zh-tw/library/microsoft.visualstudio.testtools.unittesting.assert_members.aspx)
-   [MSDN Webcast - ASP.NET MVC框架开发系列课程(9)：单元测试(Level 200)](https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=zh-CN&EventID=1032382266&CountryCode=CN)
-   [Creating Unit Tests for ASP.NET MVC Applications: The Official Microsoft ASP.NET Site](http://www.asp.net/mvc/tutorials/creating-unit-tests-for-asp-net-mvc-applications-cs)
-   [建立和執行單元測試](http://msdn.microsoft.com/zh-tw/library/dd293546.aspx)
