單元測試是應用程序設計的一個重要部分它可應用於程序的多個層次本文將主要關注用戶界面層的單元測試我們將使用WatiN 測試ASPNET應用程序
什麼是WatiN?
WatiN 是一個源自Watir的工具用於測試Web頁面WatiN表示Web Application Testing in NET
我們要測試什麼?
在本文中我們將測試一個簡單的ASPNET頁面用這個頁面來演示認同接受(agreement acceptance)的場景用戶在文本框中輸入名字點擊I agree復選框然後按下submit按鈕這顯然是一個非常簡單的頁面在你熟悉了WatiN框架的工作機制後就可以將這裡的理念用於大型頁面的測試了
測試認同(Agreement)頁面
向解決方案添加一個類庫項目並為其添加對測試工具(我這裡用的是MbUnit但你完全可以使用NUnit或VSTS的測試項目)和WatiN庫的引用你可以在這裡下載WatiN
下面的測試代碼用來確保用戶已經認同
[TestFixture(ApartmentState = ApartmentStateSTA)]public class TestAgreementPage{ [Test] public void TestCanAcceptUserAgreement() { IE ie = new IE(ConfigurationManagerAppSettings[DefaultPageUrl]); ieTextField(txtName)TypeText(Mohammad Azam); ieCheckBox(chkAgree)Checked = true; ieButton(btnAgree)Click(); AssertAreEqual(Valid ieSpan(lblMessage)Text); }}這個類有TestFixture特性(Attribute)STA值確保該測試運行於STA(Single Threaded Apartment)狀態下這是因為測試代碼要加載IE
WatiN中的IE類完成了主要工作IE類打開IE通過name或id來引用html控件這一行ieTextField(txtName) TypeText(Mohammad Azam)引用了id為txtName的文本框浏覽器加載後WatiN會將值Mohammad Azam寫入id為txtName的文本框這個過程在測試時你會看到的然後id為chkAgree的復選框會被選中最後WatiN會按下提交按鈕窗體被提交
運行測試失敗因為名為lblMessage的Label從未被賦值為Valid加上這段代碼
protected void btnAgree_Click(object sender EventArgs e){ lblMessageText = Valid; }現在如果你運行測試它會通過但是好像不太正確如果我們把這一行測試代碼刪掉
ieCheckBox(chkAgree)Checked = true; 再次運行測試依然能通過這可不對!應當只有在CheckBox選中時才可通過將頁面的Code behind代碼改一下
protected void btnAgree_Click(object sender EventArgs e){ if (chkAgreeChecked) { lblMessageText = Valid; }}現在測試只有在CheckBox選中時才可通過了
以編程方式運行Web服務器
在上例中我們需要運行WebServer要麼是通過命令行工具要麼是通過運行Web項目但有時我們需要單元測試項目能夠動態打開一個WebServer一起來看看
首先如果你需要打開ASPNET內部服務器(WebDevWebServer)可以使用命令行語法如下
WebDevWebServerexe /port: /path:C:\Projects\MyWebApplication
需要定位到WebDevWebServer所在的目錄默認情況下它在
C:\WINDOWS\MicrosoftNET\Framework\v\WebDevWebServerexe
好了現在來看看如何在單元測試中打開服務器首先添加必要的配置(Appconfig中)
BaseTestPage類可以通過這些信息運行服務器所有繼承了它的測試類都可以使用這個功能了
下面是BaseTestPage類的完整代碼
public class BaseTestPage{ static Process server = null; static BaseTestPage() { if (ProcessGetProcessesByName(WebDevWebServer)Length == ) { string webServerExePath = (string)ConfigurationManagerAppSettings[WebServerExePath]; server = new Process(); ProcessStart(webServerExePath GetWebServerArguments()); } } public static string GetWebServerArguments() { string args = StringFormat(/port:{} /path:\{}\ GetPort() GetWebApplicationPath()); if (StringIsNullOrEmpty(args)) throw new ArgumentNullException(Arguments is not defined); return args; } public static string GetPort() { string port = ConfigurationManagerAppSettings[Port] as String; if (StringIsNullOrEmpty(port)) throw new ArgumentNullException(Port is null or empty); return port; } public static string GetWebApplicationPath() { string webApplicationPath = ConfigurationManagerAppSettings[WebApplicationPath] as String; if (StringIsNullOrEmpty(webApplicationPath)) throw new ArgumentNullException(WebApplicationPath is null or empty); return webApplicationPath; }}如果服務器沒有運行我們會新建一個進程運行它否則就使用已有的進程GetWebServerArguments()GetPort()和 GetWebApplicationPath()僅僅是輔助方法可以提高可讀性
最後你可以讓單元測試類繼承該類
public class TestAgreementPage : BaseTestPage
現在運行單元測試項目時它會運行WebServer然後再執行所有測試
結論
在本文中我們學習了如何對用戶界面層進行單元測試這些測試可幫助我們理解UI的需求並快速地看到基於用戶輸入所得到的結果而如果手動進行測試就要花費很多時間了
From:http://tw.wingwit.com/Article/program/net/201311/15476.html