前言
Coded UI Test是Visual Studio 2010對於Testing Project(測試工程)提供的關於UI自動化測試的框架,支持Win32/Web/WPF等UI的自動化測試,在介紹它之前,先簡單介紹一下持續集成。大家如果對持續集成不感興趣的話,可以直接跳到第3節。
1:持續集成
持續集成由軟件工程大師Martin Fowler提出,他對技術集成下的定義是:持續集成是一種軟件開發實踐,即團隊開發成員經常集成它們的工作,通常每個成員每天至少集成一次,也就意味着每天可能會發生多次集成。每次集成都通過自動化的構建(包括編譯,發布,自動化測試)來驗證,從而盡快地發現集成錯誤。
按照持續集成的思想,代碼可以也應該能夠在一天里可以多次通過“構建”,從而能在一天之內提供多個可供測試的版本。
這里面講的構建不單單是代碼的編譯通過,它應該包含下面的步驟:
- 所有最新代碼從配置管理工具中取出.
- 所有的代碼從干凈的狀態開始編譯。
- 將編譯結果鏈接並部署,以備執行。
- 執行部署的應用並運行測試套件。
如果上述所有操作沒有任何錯誤,沒有人工干預,並通過了所有測試,才認為這是一次成功的構建。
對於第4步而言,如果應用程序是一個需要安裝到桌面的UI應用,那么就需要保證它可以成功的部署,這樣才能提供可以測試的環境。
2:我的持續集成實踐
我公司使用敏捷開發,使用CruiseControl進行代碼控制,當代碼被Check In 后, 會自動編譯,並生成一個壓縮后的exe文件,然而而當需要測試該exe文件時,需要手工從文件服務器下載,然后手工卸載已有的程序,再運行該exe安裝新的程序,確保安裝后的程序/服務正確運行后,方能進行軟件的測試。
也就是說,我們已經實現了前三步的自動化,而最后一步,由於涉及UI界面、服務卸載,一直沒有能夠自動化,這其中的一個難點就是該exe是一個較龐大且復雜的壓縮程序,在安裝時可以使用十分靈活多樣的配置,每一樣配置都會導致不同的安裝結果,如果要把所有常用的安裝方式自動化,編程的代價比較大。
在了解了Visual Studio 2010提供的Coded UI test功能后,以上問題初步得以解決,從而在技術層面,使用較小的C#代碼就完成了UI界面安裝、服務卸載等問題,從而將上述第四步與前面的三步串聯起來,初步滿足了持續集成的要求。
最后形成的大致步驟是
1:開發人員提交代碼
2:編譯服務器開始編譯,並在文件服務器上生成installer,並發出通知
3:C#程序去文件服務器下載installer,拷貝至測試服務器
4:C#程序卸載測試服務器上的原程序/服務
5:C#程序根據測試需要/測試參數安裝installer,直到完成部署進行
6:C#程序調動自動化腳本(QTP/SilkTest/Seleium),進行自動化測試
7:檢查測試結果
第3-6步都是由一個C#程序完成的,下面我主要介紹一下第5步,也就是軟件自動安裝的實現原理,在掌握了自動安裝之后,第4步,也就是軟件的自動卸載也就同樣得到解決了。
3: Coded UI test使用
Coded UI Test是對UI進行的測試,使用方法和很多支持UI自動化測試的工具(QTP、SilkTest)一樣,都支持UI的錄制、回放、識別、斷言,與這類工具相比,它主要還有如下的好處:
1:基於.Net framework,且同時支持Win32/Web/WPF,利於代碼的擴展和復用
2:可以編譯成exe文件,脫離Visual Studio運行。
3:除了支持Web/Win應用外,還支持WPF(很多自動化工具對WPF的支持並不是太好)。
3.1 錄制一個Coded UI test測試
一個復雜的installer,除了有復雜的安裝配置之外,UI界面往往也比較復雜,在不了解Coded UI test這個辦法之前,如果專門為installer寫一個控制安裝程序會是一件比較費時費力的工作,特別是當這個installer有多個設置窗口和控件時。而使用Coded UI test則可以非常輕松的解決這些問題,代碼也便於擴展。
下面以notepad++這個大家常用的小工具的安裝來說明如果建立一個Coded UI Test(由於我的Visual Studio 2010是英文版的,所以只能提供英文截圖和英文名稱),在進入下文之前,建議大家再實際下載、運行一下notepad++的安裝程序,體驗它每一個窗口的功能,以及支持的多種參數設置,並思考如果不使用自動化工具,如何編程實現程序的安裝。
我在示例中使用的版本是5.9.6,大家可以去其官方主頁http://notepad-plus-plus.org/ 下載5.9.6的版本npp.5.9.6.Installer.exe。
下面是具體的步驟
1:打開Visual Studio 2010,新建一個類型是Test的工程,如下圖
2:刪掉自動生成的第一個默認類
3:右擊工程,選擇Add,然后選擇Coded UI Test,這時會彈出一個窗口,在此選擇第一項“錄制一個新測試”,點擊OK按鈕
4:此時,在窗口的右下角會彈出一個名為Coded UI Test Builder的窗口,點擊第一個紅色圓形按鈕后,便可以進行一個UI測試的錄制,如下圖
5:在資源管理器中運行notepad++的安裝程序,任意設置安裝參數,逐個點擊Next按鈕,最后直至安裝完成。
6:點擊窗口右下側Coded UI Test Builder窗口中第4個按鈕,在彈出的窗口中將方法名稱修改為DoInstall,然后點擊Add and Generate按鈕,稍等片刻后,整個程序便會生成了,這時可以關閉Coded UI Test Builder窗口。
7:生成后的工程結構如下圖所示:
其中CodedUITest1.cs是測試類,而UIMap.uitest則包含了notepad++每個窗口的聲明,以及安裝的具體步驟,例如DoInstall的主體部分便是具體的每一步操作:
// Click 'OK' button
Mouse.Click(uIOKButton, new Point(40, 10));
// Click '&Next >' button
Mouse.Click(uINextButton, new Point(40, 7));
// Click 'I &Agree' button
Mouse.Click(uIIAgreeButton, new Point(40, 7));
// Click '&Next >' button
Mouse.Click(uINextButton, new Point(40, 7));
// Click '&Next >' button
Mouse.Click(uINextButton, new Point(40, 7));
// Select 'Create Shortcut on Desktop' check box
uICreateShortcutonDeskCheckBox.Checked = this.DoInstallParams.UICreateShortcutonDeskCheckBoxChecked;
// Click '&Install' button
Mouse.Click(uIInstallButton, new Point(40, 10));
// Clear '&Run Notepad++ v5.9.6' check box
uIRunNotepadv596CheckBox.Checked = this.DoInstallParams.UIRunNotepadv596CheckBoxChecked;
// Click '&Finish' button
Mouse.Click(uIFinishButton, new Point(41, 6));
8:如果現在按F5,程序無法運行,原因是這段代碼里沒有運行notepad++安裝程序的代碼,只是假設安裝程序已經運行了,所以我們要在第一個Click動作前面加上下面的代碼
string installer = @"c:\share\npp.5.9.6.Installer.exe";
ApplicationUnderTest InstallerWindow = pplicationUnderTest.Launch(installer);
現在再按F5試試?應該可能運行一個完整的安裝了。
程序說明:
1:在錄制第一個操作時,系統已經自動將每一個涉及到的UI界面及其包含的元素加以識別,並記錄每一次的操作(點擊、鍵入等),當生成代碼時,會把這些東東全部輸出下來。
要想查看每一個界面元素的定義,大家可以選擇任意一個元素,然后按F12,查看它的聲明,並進一步查看它所成的窗口的定義。
例如第一個被點擊的按鈕uIOKButton,它位於UIInstallerLanguageWindow中,而UIInstallerLanguageWindow則是依靠SearchProperties屬性具體定位的。
2:我們點擊按鈕、選中CheckBox,對應的操作就是Mouse.Click或者某CheckBox.Checked,如果我們有復雜的安裝需求,可以按照這樣的思路進行定制。
3:在實際的安裝或者參數的設置時,往往有某些控件不可見/不可用,只有滿足了某種條件才會可見/ 可用。就象本文的例子中,對於正在進行安裝的窗口,其Next按鈕是不可用的,見下圖:
該按鈕會在安裝完成后可用,如果程序在這時要點擊這個Next按鈕,會導致程序報錯,這時怎么辦呢?
按照很多人的編程習慣,往往會用sleep(5)來解決,但這也有問題,不同的計算機性能不同, 在一台計算機上設置好的時間,在另外一台上可能過短,如果把時間設足夠長,又會導致效率下降。
Coded UI Test提供了一系列方法處理這類問題,如下:
WaitForControlCondition():控件滿足某種條件后再往下執行
WaitForControlEnabled():控件有效后再往下執行
WaitForControlExist():控件可以被找到后再往下執行
WaitForControlNotExist():控件不存在時再往下執行
WaitForControlPropertyEqual():控件的某個屬性等於等值后再往下執行
WaitForControlPropertyNotEqual():控件的某個屬性不等於等值后再往下執行
WaitForControlReady():控件准備就序后再往下執行
這樣,對上同樣例子中的倒數第二行代碼,在程序安裝時,由於要花費一定的時間,uIRunNotepadv596CheckBox所處的窗口還沒有顯現,uIRunNotepadv596CheckBox自然還無效,因此,對於性能較的計算機,執行到這句話時可能出錯,為了保險,可以在之前增加一行代碼:
uIRunNotepadv596CheckBox. WaitForControlReady();
然后再執行后面的:
uIRunNotepadv596CheckBox.Checked = this.DoInstallParams.UIRunNotepadv596CheckBoxChecked;
就可以保證該控件是在有效的情況下執行后面的操作了。
4:控件的名稱、窗口的名稱都是程序自動生成的,如果覺得命名不好,可以用Visual Studio 提供的重構-改名功能進行替換。
5:程序的入口是public void CodedUITestMethod1(),默認是無參數的,如果需要在安裝中設置復雜的參數,以及把安裝程序的路徑傳遞進去,可以在此增加參數,然后把參數傳遞到具體的執行方法DoInstall()
3.2 讓程序脫離Visual Studio執行
以上的代碼只能Visual Studio中運行,要想讓它脫離Visual Studio也能運行,需要做如下操作。
1:增加一個類,假設名稱是TestMagager,加入如下代碼
public static void Init()
{
if (!Playback.IsInitialized)
{
Playback.Initialize();
}
}
2:新建另一個工程(可以是Windows,也或以是類庫),引用上述的測試工程,然后在代碼先中調Init(),然后直接調用安裝的主程序,如下:
TestMagager.Init();
CodedUITest1 t = new CodedUITest1();
t.CodedUITestMethod1();
3:這個新建的工程編譯成功后,理論上調用上述的代碼可以進行軟件的安裝,但此時會報錯誤,提示所需要的DLL文件不存在,其原因是:
對於Test類工程,Visual Studio 可以找到依賴的DLL文件,然而被引用由其它的程序調用后,便不能找到這些文件,只要手工把它們拷貝到一個統一的目錄,然后引用到新建的工程就可以了,這些文件是:
Microsoft.VisualStudio.QualityTools.CodedUITestFramework.dll
Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll
Microsoft.VisualStudio.QualityTools.UnitTestFramework.xml
Microsoft.VisualStudio.TestTools.TestSettings.Common.dll
Microsoft.VisualStudio.TestTools.TestSettings.dll
Microsoft.VisualStudio.TestTools.UITest.CodeGeneration.dll
Microsoft.VisualStudio.TestTools.UITest.CodeGeneration.xml
Microsoft.VisualStudio.TestTools.UITest.Common.dll
Microsoft.VisualStudio.TestTools.UITest.Common.xml
Microsoft.VisualStudio.TestTools.UITest.Extension.dll
Microsoft.VisualStudio.TestTools.UITest.Extension.IE.Communication.Interop.dll
Microsoft.VisualStudio.TestTools.UITest.Extension.IE.dll
Microsoft.VisualStudio.TestTools.UITest.Extension.MSAA.dll
Microsoft.VisualStudio.TestTools.UITest.Extension.Uia.dll
Microsoft.VisualStudio.TestTools.UITest.Extension.xml
Microsoft.VisualStudio.TestTools.UITest.Framework.dll
Microsoft.VisualStudio.TestTools.UITest.Playback.dll
Microsoft.VisualStudio.TestTools.UITest.Recorder.dll
Microsoft.VisualStudio.TestTools.UITesting.dll
Microsoft.VisualStudio.TestTools.UITesting.dll
在Visual Studio的安裝目錄下搜索,可以找到這些文件,它們分別存儲在\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies和
\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies目錄下,把它們拷到一個目錄中,然后在應用中全部引用,便可以運行新建的這個工程了。
3.3 示例程序
Coded UI Test程序地址是:點擊這里
解壓縮后,一共有兩個文件夾,第一個是Coded UI Test工程,第二個是Winform對它的調用。
因為偷懶,所有Project的文件全是系統默認的,生成的代碼也沒有重構,Coded UI Test工程用硬代碼的方式運行Notepad++的安裝程序(c:\share\ npp.5.9.6.Installer.exe),建議大家以參考代碼結構為主,自己動手來建立一個類似的運行程序。
如果大家真的要運行示例程序,需要c:\share\ npp.5.9.6.Installer.exe這個程序存在,而且在安裝Visual Studio 2010時,安裝對測試工程的支持。
最后再說明,我已經把英文Visual Studio 2010的dll文件拷貝到了WindowsFormsApplication1的bin\debug目錄下,並且在XP環境下測試通過。
使用上面的思路,還可以實現程序的自動卸載。
后記:按照上述方法,我實現了幾個應用程序(包括服務)的自動安裝、卸載,從而實現了上文提到的自動部署、測試,初步實現持續集成。
本人對Coded UI Test了解也僅限於此,如有不正確的地方,歡迎批評指正,多謝!