單元測試及測試驅動開發簡介
什么是單元測試
單元測試是一段自動化的代碼,這段代碼調用被測試的工作單元,之后對這個單元的單個最終結果的某些假設進行檢驗。單元測試幾乎都是用單元測試框架編寫的。單元測試容易編寫,能快速運行。單元測試可靠、可讀、並且可維護。只要產品代碼不發生變化,單元測試的結果是穩定的。
特征:
• 自動化、可重復執行;
• 很容易實現;
• 第二天還有意義;
• 任何人都應該能一鍵運行它;
• 運行速度應該很快;
• 結果應該是穩定的;
• 能完全控制被測試的單元;
• 完全隔離(獨立於其他測試的運行);
單元測試命名
由於單元測試非常強調可讀性,因此我們要花些功夫在命名上,要使單元測試方法名簡單易懂,基本一下子能看出它的主要功能.如果覺得方法名不能夠完全表達出此方法要實現的功能,也可以額外添加注釋.推薦的命名方式如下
Should_Return(Throw)_Result(exception)_If(when)But
其中Should表示期待一個結果,Return或者Throw為要測試方法期待的返回結果,If表示出現以上結果需要的條件,But為附加條件.
什么是集成測試
集成測試是對一個工作單元進行的測試,這個測試對被測試的工作單元沒有完全的控制,並使用該單元的一個或多個真實依賴物,例如時間,網絡、數據庫、線程或隨機數產生器等。
單元測試與集成測試的區別
單元測試與集成測試最大的區別在於:集成測試依賴於一個或多個真實的模塊,當運行集成測試時,出現失敗的情況后你並不能立即判斷是哪里出了問題,因此找到缺陷的根源會比較困難。
測試驅動開發
傳統開發流程
[虛線代表是一個可選的行為]
TDD開發流程
由上面的兩個圖中可以看出TDD與傳統開發模式的區別:先編寫一個會失敗的測試,然后創建產品代碼,並確保這個測試通過,接下來是重構代碼或者創建另一個會失敗的測試。
單元測試框架作用
單元測試框架是幫助開發人員進行單元測試的代碼庫和模塊。
Nunit單元測試框架使用
NUnit 是一套開源的基於.NET平台的類Xunit白盒測試架構,支持所有的.NET平台。這套架構的特點是開源,使用方便,功能齊全。很適合作為.NET語言開發的產品模塊的白盒測試框架。
起初是從流行的Java單元測試框架JUnit直接移植過來的,之后NUnit在設計和可用性上做了極大地改進,和JUnit有了很大的區別,給日新月異的測試框架生態系統注入了新的活力。
如何在VS安裝並運行呢?用Nuget是最方便的一種形式了,如下圖:
如果各位的visualStudio中安裝有Resharper插件,則只需要安裝紅色部分框選的內容即可,如果沒有安裝也沒有關系,可以使用VisualStudio自帶的測試工具也是可以的,
以下講解用的也是VisualStudio自帶的測試工具.
需要注意的是如果使用VisualStudio自帶的測試工具,還需要安裝Nunit.Console
編寫第一個單元測試
我們在剛才新建的項目中添加一個名為FirstUnitTest的項目
我們要引入using NUnit.Framework;方可使用Nunit
我們新建的第一個測試代碼如下
其中TestFixture注解標識這個類為單元測試類,如果沒有此標識,則此類無法在單元測試工具中運行
方法上的Test注解標注此方法為一個單元測試方法,如果沒有Test注解,則此方法在單元測試運行的時候將會被忽略掉
類注解和方法注解添加以后,單元測試就可以跑起來了.
運行第一個單元測試
使用VisualStudio自帶單元測試工具運行
如上圖示,點擊菜單欄的Test(測試)-Windows(窗口)-Test Explorer(測試瀏覽器)便可以在VisualStudio中打開測試瀏覽器,只要我們保存了項目,就可以在Test Explorer中看到剛才創建的單元測試了(剛創建的單元測試名為FirstUnitTest)
運行單元測試,我們點擊Test Explorer中FirstUnitTest下的測試方法名,出現以下選項
我們點擊Run Selected Test(運行選中的單元測試)便可以運行這個單元測試了
運行以后便可以在Test Explorer中看到結果了
單元測試圖標含義
單元測試結果很容易根據圖標看出來其含義,其中圓圈內一個紅色X 號代表測試失敗,需要處理,圓圈里一個綠色對勾 代表測試成功,菱形內一個藍底! 號代表測試結果待定(單元測試沒有運行的狀態是待定)
除了這幾個狀態外還有一種狀態是三角形內一個黃底感嘆號 ,代表警示,后面會介紹這個狀態.
單元測試狀態查看
通過以上狀態我們很清析地看到我們創建的單元測試失敗了,我們點擊這個單元測試,Test Explorer下面部分便會顯示關於這次測試的基本信息
我們從錯誤信息里可以看到錯誤原因是期待的結果True,實際上是False.如果測試過程中由於異常導致錯誤,StackTrace還會顯示異常的堆棧信息.
小技巧-快速定位到錯誤方法:在實際工作中,隨意項目的深入,測試方法會越來越多,我們寫完一個測試方法后然后點擊測試,這樣不會有什么問題,然后實際情況是隨着測試方法積累越來越多,我們日后要運行單元測試的時候往往是點擊整個單元測試項目運行,這時候如果有錯誤我們雖然可以根據方法名定位到出錯的測試方法,然而這樣很不方便,我們這時候可以點擊錯誤信息欄里的Source后面的藍色文字,快速定位到測試出現錯誤的方法.
很多時候我們只是查看一下這個面板,並不把鼠標移過來點擊,更為快捷的定位到錯誤方法的的方式是我們選中測試方法后,直接按下快捷鍵F12,就直接進入到錯誤方法了
上面的面板中展示有錯誤的信息,如果信息過長時在面板查看很不方便,這時候我們可以把它復制下來然后在自己喜歡的文本查看器中查看
單元測試調試
通過以上狀態我們知道我們的單元測試失敗了,為什么會失敗很簡單3+4*5/2不等於0,但是很多時候有些結果不是這么顯而易見的,我們需要借助單步調試來發現錯誤,如何對單元測試進行調試呢?
首先我們像普通調試一樣設置一個斷點,然后在Test Explorer中右擊方法名,出現彈出菜單,這次我們選擇Debug Select Tests(調試選擇測試)
此時我們會看到像我們普通調試一樣,斷點被擊中
我們可以在斷點調試模式發現錯誤所在.
這里還有一點需要指出的是,單元測試的成功失敗狀態只是針對本次有效,如果關閉VisualStudio所有的狀態又會變成待定狀態,需要再次運行測試才會有成功,失敗等狀態.
使用Resharper運行單元測試
Resharper為VisualStudio的一個插件,集成了很多功能,其中包含單元測試運行功能.如果你的VisualStudio里安裝的Resharper插件,也可以使用Resharper來運行單元測試,使用Resharper來進行測試測試比使用VisualStudio自帶的單元測試工具更為方便.
如果安裝了Resharper,VisualStudio的主菜單里會出現Resharper菜單,執行以下圖示操作便可以打開Resharper Unit Test Explorer
窗口和VisualStudio Test Explorer類似
操作也和VisualStudio自帶的Test Explorer操作類似,點擊剛才新創建的FirstUnitTest類,便會出現以下菜單
選擇第一個Run Unit Test便會運行單元測試,點擊Debug Unit Tests則會進入單元測試調試模式,和VisualStudio自帶的測試工具操作類似.
執行結果狀態圖標和Visual Studio自帶的測試工具狀態圖標大同小異,很容易區分
一點很大的不同在於它的單元測試信息顯示在右邊,這樣如果面板的寬度過小而錯誤信息過長就會出現如下圖示情況
基本上不可讀
我們可以通過如圖示設置把它調到下面,這樣就和VisualStudio自帶的單元測試工具布局基本一樣了
同樣可以點擊藍色或者青色文字快速導航到錯誤方法里.
同樣,由於面板大小限制,如果錯誤內容信息過豐富查看起來不是很方便,VisualStudio自帶的測試工具可以通過Copy All復制到剪切板,然而這個面板並沒有,沒有辦法把錯誤記錄復制出來嗎,答案是有的.
我們右擊方法名,便會出現下面一個級聯菜單
這里有導出Text,XML和HTML,導出到xml和html基本上不需要,只需要導出為Text即可,點擊Export to Text出現如下對話框
如果我們選擇一個路徑便會將錯誤導出,很多時候並不需要這么做,我們點擊Copy to Clipborard把內容復制到剪輯板,便可以把它復制到自己喜歡的文本編輯器里查看了
Resharper測試技巧-狀態過濾
當測試越來越多的時候,我們往往對整個測試項目進行運行,而不是像在開發階段寫一個運行一個,有人可能會有疑問,單元測試寫的時候測試通過,以后再測會變成不通過狀態嗎,答案是肯定的.如果我們的單元測試中包含外部依賴(理想狀態下不應該包含),往往外部依賴的變化會導致單元測試結果的變化.另外,單元測試編寫的不恰當也會引起測試結果的變化.外部依賴的變化往往由於項目本身原因耦合度太高,一時又無法重構但仍然需要單元測試,這時候也可以勉強為之,然而不恰當的測試代碼導致結果的不穩定是需要避免的.(最為常見的是日期中使用DateTime.Now由於Datetime.Now是變化的導致單元測試結果不可預測,這種情況是需要避免的.)
以上穿插的內容只是為了說明特定情況下單元測試的結果是會變的,因此不以為編寫完測試方法后運行一遍成功就萬事大吉.
如果測試方法很多,運行完以后出現多處錯誤,此時想要一個個找出失敗的單元測試不是很方便,此時我們可以借助Resharper Unit Test Explorer中的測試狀態過濾功能來過濾出所有的錯誤測試.
如上圖,我們點擊上面工具欄里的錯誤圖標,這時候Explorer里列出的全部都是錯誤測試.
需要注意的是,由於我們啟用的過濾,一旦錯誤都解決以后,這里便沒有錯誤測試可羅列,這時候這里變成一片空白,我們需要點擊一下最左邊所有測試圖標把所有測試都顯示出來
Resharper測試技巧之類內部啟用測試
現在的測試還比較少,我們在Test Explorer中找到剛剛編寫好的單元測試方法並不是一件很困難的事,但是當Explorer里單元測試方法越來越多的時候,想要快速找到剛編寫好的方法啟動是一件非常繁瑣的事,
我們往往需要把方法名復制下來,然后粘貼到Explorer(這里的Explorer根據語境指的是Resharper Unit Test Explorer或者VisualStudio Test Explorer,並非windows explorer或者其它)里面,啟動后還要刪除查找內容,如果不刪除則其它的方法都無法展示出來了.Resharper提供了一些非常貼心的簡便功能,可以直接在類內部直接啟動單元測試,而不需要到Explorer里找到測試方法然后運行.
如上圖示.當一個方法有了Test注解,Resharper便能感知它,這時候方法的前面出現一個如上圖紅框框選的陰陽圖標
點擊圖標便會出現以下上下文菜單
點擊Run便可以運行測試.
運行成功這時候陰陽圖標右下角會有一個綠色小對勾指示測試成功
如果點擊類名前面的雙陰陽圖標則會整個類的所有測試方法進行操作
這時的Run和Debug后面都有一個All字,表示對此類的所有方法運行測試或者調試.