進行UI介面的單元測試 實作與工具篇 (OneNet魔力小子)
本篇是主要在介紹 UI(使用者介面)的單元測試,在寫單元測試中最讓人頭痛的就是 UI層很難進行測試,尤其是UI層與邏輯層的程式耦合度很高的程式專案,而 NUnitForms 就是用來解決這個問題的良好工具,NUnitForms是作為NUnit的擴展,他主要的用途是專為Windows Forms應用程式的表單測試而設計的。
NUnitForms 可以跟 NUnit(單元測試)進行良好的配合機制,在撰寫NUnit單元測試的程式碼中,可以利用NUnitForms 的來跟Windows Form進行互動,過程中不需要再經由User(使用者)進行人工操作,因此可以用來模擬使用者操作UI的輸入,來進行接受性的單元測試,NUnit目前可以支援的控制項元素包含需多,如:Buttons, CheckBoxes, ComboBoxes, Labels, ListBoxes, RadioButtons, TabControls, TextBoxes, TreeViews, Context Menus, Forms, MenuItems, Modal Forms, Modal MessageBoxes, and the Mouse 。
官方網站:http://nunitforms.sourceforge.net/index.html
下載NUnitForms,並安裝完成後,就可以新增一個程式類別專案,對NUnitForm.dll的參考引用,步驟如下:
先新增一個類別專案
在專案的參考節點上按右鍵進行參考引用 NUnitForm.dll
引用NUnitForms.dll檔後,在命名空間添加
using NUnit.Extensions;
using NUnit.Extensions.Forms;
上述步驟完成後,接下要在單元測試程式碼(NUnit)中針對將要進行測試的Windows Form(表單),需要執行類似下列語法來初始化。
Form1 form = new Fom1();
//進行Form.Show()來顯示啟用表單
form.Show();
這邊有個觀念需要先特別說明,在NUnitForms框架中,已經實作出很多測試表單(Windows Form)過程中,可以模擬的Control,因此在寫單元測試中,可以根據實際需要模擬的Control,進行宣告物件實體,例如要模擬表單的TextBox,就可以新建一個Object 為 TextBoxTester,模擬Button按鈕,就可以新建立一個 ButtonTester,仔細觀察你會發現,結尾都是Tester居多,而這些模擬的Control都是延自一個基類為 ControlTester。而每個 ***Tester都有提供一些方法與屬性,來供程式呼叫與使用,以下特別撰寫這幾個範例:
ex1:
//使用 ControlTester 來存取 TestBox 控制項的屬性
ControlTester textBoxTest = new ControlTester("textBox1") ; // textBox1為Windows Form表單上的TextBox控制項ID
ex2:
//使用 ControlTester 來存取 Button 控制項的屬性
ControlTester buttonTest = new ControlTester("button1"); // button1為Windows Form表單上的Button控制項ID
ex3:
// 抓取某個 Form (在此為form1) 上的 button1 控制項
// 如果忽略掉 form1 參數,則NUnitForm將搜尋所有以呼叫 Form.Show() 的表單
ControlTester buttonByFormIdTest = new ControlTester("button1", "form1");
根據上述語法,將可以順利取得要測試的Control項目,以下根據上述在繼續寫幾個範例,來讀取控制項的屬性或呼叫歸屬方法:
ex1:
//使用 ControlTester 來存取 TestBox 控制項的屬性
ControlTester textBoxTest = new ControlTester("textBox1") ; // textBox1為Windows Form表單上的TextBox控制項ID
//讀取 TextBox.Text , 並列印出
System.Console.Out.WriteLine(textBoxTest["Text"].ToString());
ex2:
//使用 ControlTester 來存取 Button 控制項的屬性
// button1為Windows Form表單上的Button控制項ID
ControlTester buttonTest = new ControlTester("button1");
//觸發Button.Click()方法
buttonTest.FireEvent("Click", new EventArgs());
ex3:
//利用 ButtonTester 來測試 Button 作法
ButtonTester buttonTest2 = new ButtonTester("button1");
//引用Button.Click() 方法
buttonTest2.Click();
[案例分享]
接下來,筆者將完成一個實作案例,來完成NUnit與NUnitForms的測試案例,案例將模擬有一個Windows Form表單,而這個表單擁有一個Button控制項、一個TestBox控制項、以及一個Label控制項,然後在使用NUnit(單元測試)與NUnitForms,實作出模擬預期使用者操作Form表單後,將出現的值來進行測試案例。 (本篇假設讀者已知NUnit單元測試的實作技巧)
現在在專案裡新增一個Windows Form,並取名為form1
在form1,從工具項拖拉Button、TextBox、Label控制項到 form1 裡
在button1.Click() (雙點擊button1),撰寫下列語法:
1: private void button1_Click(object sender, EventArgs e)
2: {
3: //TextBox輸入字串顯示至Label
4: this.label1.Text = this.textBox1.Text;
5: }
在專案裡,在新增一個Class,並命名為 NUnitFormsTest.cs,如下圖:
在專案裡參考引用 unit.framework.dll 與 NUnitForms.dll
在NUnitFormsTest.cs 引用下列命名空間
using NUnit.Framework;
using NUnit.Extensions.Forms;
撰寫下列整合NUnitForms程式碼
1: // [TestFixture] 標示此 Class 為 NUnit 測試用途
2: [TestFixture]
3: public class NUnitFormsTest
4: {
5:
6: // [Test] 標示此 Method 為 NUnit的測試方法
7: [Test]
8: public void Test01_ButtonClick()
9: {
10: //new form1 object and Show form1
11: form1 form = new form1();
12: form.Show();
13:
14: TextBoxTester txtTest = new TextBoxTester("textBox1");
15: //模擬使用者 KeyIn 值
16: txtTest["Text"] = "輸入值測試";
17:
18: ButtonTester btnTest = new ButtonTester("button1");
19: //呼叫Button.Click()
20: btnTest.Click();
21:
22: LabelTester lblTest = new LabelTester("label1");
23:
24: //進行測試
25: Assert.AreEqual("輸入值測試", lblTest["Text"].ToString(), "Error Value Not Mapping..");
26:
27: }
28: }
在此省略掉NUnit的技巧,如果改天還有時間,我將會補齊這塊NUnit測試技巧。