Windows UIA自動化測試框架學習–獲取qq好友列表
前段時間應公司要求開發一款針對現有WPF程序的自動化測試工具,在網上查資料找了一段時間,發現用來做自動化測試的框架還是比較多的,比如python的兩個模塊pywinauto和uiautomation,但是pywinauto主要是封裝Win32的api,只局限於winform框架,而python中的uiautomation其實是封裝的windows中的uia框架。基於項目效率考慮,所以最後決定使用windows中的UIAutomation框架。
這款WindowsUIA框架是同時支持wpf和winform,由於公司項目主要是wpf為主,所以以下學習和舉例也是基於wpf框架,沒有深入研究winform下的差異,但是大體上還是差不多的。
僅僅作為客戶端來invoke的話,只需要引用下面兩個dll即可,可以在.Net框架中查找:UIAutomationClient.dll,UIAutomationTypes.dll
在UIA框架中,所有元素包括窗口和控件都表現為AutomationElement。一個進程中的UI在空間上分佈在一棵UI樹上面,只需要找到UI樹的根元素,就可以檢索到與之相關聯的其他任何元素
查找窗口
查找每個進程的根元素最常用的是根據控件句柄查找,方法如下:
但是這個框架沒有提供檢索句柄的功能,所以需要和API配合使用:
private static extern IntPtr findWindow(string lpClassName, string lpWindowName);
根據這個API獲取某個窗口的句柄,根據這個窗口的句柄獲取到AutomationElement,然後就可以通過下面的方法來查找其他元素
以上兩個方法可以搜索到這顆UI樹上的所有子控件,例如查找某個Name屬性為MyButton的Button控件並觸發它的點擊事件,就可以這樣實現:
PropertyCondition typeProperty = new PropertyCondition(AutomationElement.IsInvokePatternAvailableProperty, true); PropertyCondition nameProperty = new PropertyCondition(AutomationElement.AutomationIdProperty, 「MyButton」);//搜索條件 AutomationElement ele = _mainAutomationElement.FindFirst(TreeScope.Subtree, new AndCondition(typeProperty, nameProperty)); if (ele != null) { if (ele.Current.IsEnabled) { InvokePattern pattern = (InvokePattern)ele.GetCurrentPattern(InvokePattern.Pattern); pattern.Invoke();//觸發點擊事件 } }
需要注意的是WPF中控件的屬性映射到AutomationElement有以下對應關係
Control property in WPF | Property in AutomationElement |
Name | AutomationIdProperty |
Content | Name |
Title | Name |
窗口的Title和繼承ContentControl 的控件的Content 都會映射為AutomationElement中的Name屬性
通過上述方法,基本可以查找到WPF中所有常用的控件,至於三方控件也有一定的兼容性。
基於以上信息,我們可以開發一個小工具,用於讀取QQ軟件的好友列表。
讀取QQ軟件的好友列表
這個小功能還是通過win32API+UIA框架實現的,獲取到qq好友列表中的成員備註名稱,圖中的好友姓名只取姓氏。
用到的API如下:
第一個API是為了獲取qq窗口的句柄,第二個和第三個是用來模擬鼠標操作。
主程序代碼很簡單,基本流程是先檢索到列表名稱的控件,然後通過獲取坐標控制鼠標點擊將列表展開,檢索該列表中所有的成員。檢索完成後將列表重新隱藏,避免列表成員太多,列表太長,影響下一個列表的展開。
通過控制鼠標的API和UIA框架基本可以實現模擬任何人為操作,對實現windows app自動化測試是一個不錯的選擇