基於UI Automation的自動化測試工具設計指南

說明:如下內容是根據2010年我在公司的一次關於UI Automation的Workshop上的PPT整理而來,在公司我和幾位同事基於UI Automation開發了一款很是強大的UI自動化測試工具,此工具已經在公司獲得普遍運用(有十幾個產品採用),用於替代昂貴的、且腳本很難維護的商用軟件。此文只探討UIA相關的一些通用技術和一點點UI自動化測試工具的設計經驗,由於保密的須要,涉及到公司的這款測試工具部分此文不作介紹。正則表達式

在沒有MSUIA(Microsoft UI Automation,如下簡稱UIA)以前,你們只能經過MSAA(Microsoft Active Accessibility)、Win32 API等Native的方式來操控Windows控件,要想本身寫一個UI自動化測試工具是很難很難的,所以這一領域一直被大廠商所壟斷,價格也貴得驚人,不是大的軟件公司也是用不起這些工具的(除非盜版),好比QTP、Robot、SilkTest等商用工具。UIA定義了一套全新的、針對UI自動化的接口和模式,以往的Win32和MSAA設計出發點並非爲解決UI自動化(Win32旨在提供的通用開發接口,MSAA技術的初衷則是爲了方便殘疾人使用Windows 程序),而UIA的設計目的(微軟也須要一套技術、工具來自動化測試本身的產品)、以及新引入的模式和接口都徹底是針對UI自動化測試的。UIA的出現,讓草根UI自動化測試工具成爲一種可能,看完本文你如有這樣的需求就趕忙本身造一個吧:)架構

在繼續介紹UIA以前,你們須要先熟悉UIA的幾個名詞術語。app

UIA名詞解釋

Elements

在UIA裏,每個UI控件便是一個Automation Element,全部的Elements是存儲在一個樹狀結構中的,Windows的桌面是這顆樹的根結點(RootElement)。ide

Tree

UIA tree就是上面所指的樹,每一個Application均可以看做是一棵子樹。工具

Properties

Element都有一些屬性(Properties),好比Automation ID、Name、ControlType等,要找到一個控件主要是經過這些的屬性來查找的。測試

Control patterns

在找到一個控件後,對一個控件進行操控的時候就須要用到這個控件支持的控制模式(Control patterns)了,好比:一個TextBox的ValuePattern能夠用來獲取TextBox裏面的文字。ui

Event

當UI控件有什麼變更的時候,可能會觸發一些事件(好比:彈出HelpText),若是有Client訂閱了這個事件則會收到事件的通知。this

UIA的架構

上圖左邊那部分叫Client,本文指的是UI自動化測試工具,右邊叫Application,指的是被測運用程序。Client和Application在啓動的時候都會載入UI Automation Core(UIAutomationCore.dll),UI自動化測試工具就是經過UI Automation Core來操控運用程序的。從這個架構圖上也能夠看到UIA封裝了一些MSAA和Win32的接口、屏蔽了Win32和.NET運用程序的差別,UI Automation Core對外提供了統一的接口,這也就大大簡化了Client這邊的實現。spa

基於UIA這套體系實現UI自動化須要解決的兩個核心的問題,一是控件查找(Find Controls);二是控件操做(Control manipulation),下面對此分別進行介紹。設計

控件查找(Find Controls)

UIA除了提供了最基本的遍歷整個UIA tree的API(TreeWalker)外,另外也提供了一些Build-in的控件查找API。

TreeWalker

  • GetFirstChild
  • GetNextSibling
  • GetParent

TreeWalker是標準的對UIA tree的遍歷API,它是一切控件查找API的基礎。

Build-in Finding(基於scope和filting condition的查找API)

  • FindFirst(TreeScope, Condition)
  • FindAll(TreeScope, Condition)

UIA自帶的這些Build-in的查找API是基於TreeScope和Filting Condition的,查找控件須要定義一個查找範圍和過濾條件。

  • 查找範圍(TreeScope)是子結點、子孫結點、父結點等這樣的樹中的範圍定義。
  • 過濾條件(Filting Condition)能夠是邏輯條件(AndCondition、 OrCondition、NotCondition等)也能夠是屬性條件(PropertyCondition)

下面是一個最簡單的示例,在RootElement桌面下查找子結點裏Name屬性是「Simple App」的一個控件,由於是在桌面的子結點(一級),它會是一個Application:

Condition winNameCond = new PropertyCondition(AutomationElement.NameProperty, "Simple App");
 
AutomationElement app = AutomationElement.RootElement.FindFirst(TreeScope.Children, winNameCond)

控件操做(Control manipulation)

經過上面的Find Controls找到一個控件後,接下來就是如何操做它實現UI自動化的問題了,好比:點擊一個Button,選擇一個TreeViewItem等等。下面是一個已作好封裝的UITextBox這個控件類裏獲取TextBox的文字的參考實現:

public virtual string GetText()
{
    object o = new object();
    if (this.Element.TryGetCurrentPattern(ValuePattern.Pattern, out o))
    {
        ValuePattern pattern = o as ValuePattern;
        return pattern.Current.Value;
    }
    else
    {
        return "";
    }
}

如上面的代碼所示,控件操做有一個固定的模式,首先嚐試獲取控件的Control Pattern,若是控件存在這樣的Control Pattern就經過這個Pattern來操控控件,若是沒有則須要自定義這個操做或拋出異常等。

UI自動化測試工具設計

直接基於UIA來實現UI自動化不是不能夠,但沒有人會這麼蠻幹。爲了獲取一個Textbox裏的文字這樣簡單的事情,獲得處拷貝上面那段的代碼,這是不可取的。因此針對上面說的兩個核心的問題,咱們須要在UIA上進行一些簡化、封裝(固然光有這兩點是不夠的,好比還須要提供一些Native的支持、UI同步、Log等功能,本文對此不作討論):

簡化、強化控件查找

  1. 簡化是指簡化控件查找API,爲了找一個控件就須要寫一大堆的Code來定義這樣那樣的過濾條件(見控件查找部分的示例代碼),若是能用一個簡單的字符串就統一全部這些那就方便多了,很負責的說咱們就是這麼幹的,Automation ID、Name、ControlType、Point、Index、或邏輯、與邏輯、通配符、正則表達式、關鍵路徑查找等雜七雜八的各類數據類型通通放到一個字符串裏搞定,這也是咱們開發的這個工具很是強大的一個地方。
  2. 強化是指強化控件查找功能,UIA Build-in的查找功能的過濾條件是比較簡單的,功能也是很是有限的,好比沒有對根據通配符、正則表達式來查找的支持,可是咱們能夠經過最基本的TreeWalker的API來擴展實現這樣的查找功能。

封裝控件的操控

封裝經常使用控件的基本操做,如:Button的Click、TreeView的Expand和Collapse、Datagrid的操做等等,使控件的操做變成一個簡單的API調用,能夠考慮把UIA ControlType裏定義的30幾種控件中最經常使用的控件基本操做都實現了,這樣寫測試腳本的時候就很安逸了。一些產品中可能會使用一些非標的控件,對於這些自定義的控件,用標準控件的操控API可能無論用,一般經過下面兩種方式來解決這個問題,一是繼承標準控件,重寫操控API的實現,若是可以實現的話;二是讓開發人員改代碼,儘可能不要使用非標控件:)

UI自動化測試framework設計

當有了應手的測試工具後,測試腳本的維護依然是個老大難的問題,這個須要有一個好的自動化測試framework來隔離UI的變化,儘可能減小維護成本,一個好的framework大致須要有下面幾級的分層:

  1. Core - framework的核心和通用模塊,好比:TestCaseBase、Config、WatchDog、Env、OS、DB操做的封裝等等。
  2. Dialogs - UI Application、Dialog、Control屬性的定義,對於一個大的UI dialog,爲了方便組織是能夠考慮切片成一些小的虛擬的Dialogs的。在Dialogs儘可能不要涉及操做邏輯,只放屬性的定義就能夠了。
  3. Key words 或者叫 Wrapper - Key words是按case(測試用例)層面的需求抽象出來的,大致對應到case裏的一個操做步驟,這一個操做步驟實際上能夠包含在一個或多個UI dialogs上的操做組合,好比:用戶登陸能夠是一個Key word,但它實際上包含了輸入用戶名、輸入密碼、點擊登陸按鈕等操做步驟。有了Key words對UI Dialog的封裝,基本上能夠作到在UI變化的時候,只修改Dialogs的定義,Key words的實現代碼不多改動,cases的代碼則無需修改(只要case的邏輯沒有發生變化)。
  4. Test cases - 到了cases層面問題就變得簡單了,就是一些Key words的簡單組合,再加上一些測試結果的驗證就OK了。

總之,經過UIA實現一套本身的強大的UI自動化測試工具不是不可能,但願本文對一些從事UI自動化測試的同窗有所幫助。

 

原文地址:http://feilong.me/2011/01/ms-ui-automation-tool-design-guide

相關文章
相關標籤/搜索