單元測試及測試驅動開發簡介
什麼是單元測試
單元測試是一段自動化的程式碼,這段程式碼呼叫被測試的工作單元,之後對這個單元的單個最終結果的某些假設進行檢驗。單元測試幾乎都是用單元測試框架編寫的。單元測試容易編寫,能快速執行。單元測試可靠、可讀、並且可維護。只要產品程式碼不發生變化,單元測試的結果是穩定的。
特徵:
• 自動化、可重複執行;
• 很容易實現;
• 第二天還有意義;
• 任何人都應該能一鍵執行它;
• 執行速度應該很快;
• 結果應該是穩定的;
• 能完全控制被測試的單元;
• 完全隔離(獨立於其他測試的執行);
單元測試命名
由於單元測試非常強調可讀性,因此我們要花些功夫在命名上,要使單元測試方法名簡單易懂,基本一下子能看出它的主要功能.如果覺得方法名不能夠完全表達出此方法要實現的功能,也可以額外新增註釋.推薦的命名方式如下
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字,表示對此類的所有方法執行測試或者除錯.