UI自動化 --- UI Automation 基礎詳解

2023-07-10 09:00:56

引言

上一篇文章UI自動化 --- 微軟UI Automation中,介紹了UI Automation能夠做什麼,且藉助 Inspect.exe 工具完成了一個模擬點選操作的Demo,文章結尾也提出了自己的一些想法,想要藉助UI Automation做一個UI自動化測試平臺。想法畢竟是想法,還是得落地實踐,一步一步來。

本篇文章內容詳細學習UI Automation 的基礎知識。

UI Automation 基礎

上一篇文章中提到 UIAutomation 通過五個元件實現程式設計存取:

  • UI Automation tree(UI自動化樹)
  • UI Automation elements(UI自動化元素)
  • UI Automation properties(UI自動化屬性)
  • Control patterns(控制元件模式)
  • UI Automation events(UI自動化事件)

接下來一一學習,以下內容翻譯自微軟官方檔案(https://learn.microsoft.com/en-us/dotnet/framework/ui-automation/ui-automation-fundamentals)。

UI Automation tree(UI自動化樹)

UI自動化樹可以通過過濾來建立僅包含特定使用者端相關的 AutomationElement 物件的檢視。這種方法允許使用者端根據其特定需求自定義通過UI自動化呈現的結構。

使用者端有兩種方式來自定義檢視:通過作用域和過濾。作用域是定義檢視的範圍,從一個基本元素開始:例如,應用程式可能只想查詢桌面的直接子元素,或者某個應用程式視窗的所有後代元素。過濾是定義要包含在檢視中的元素型別。

UI自動化提供程式通過在元素上定義屬性來支援過濾,包括 IsControlElementPropertyIsContentElementProperty 屬性。

UI自動化提供了三個預設檢視:原始檢視控制元件檢視內容檢視

這些檢視是根據執行的過濾型別定義的;任何檢視的作用域由應用程式定義。此外,應用程式還可以對屬性應用其他過濾器;例如,只在控制元件檢視中包含已啟用的控制元件。

原始檢視(Raw View)

UI自動化樹的原始檢視是以桌面為Root的 AutomationElement 物件的完整樹。原始檢視緊密遵循應用程式的本機程式設計結構,因此是最詳細的可用檢視。它也是其他檢視構建的基礎。由於該檢視依賴於底層UI框架,因此WPF按鈕的原始檢視將與Win32按鈕的原始檢視不同。

通過在不指定屬性的情況下搜尋元素或使用 RawViewWalker 瀏覽樹,可以獲得原始檢視。

AutomationElement elementNode = TreeWalker.RawViewWalker.GetFirstChild(AutomationElement.RootElement);

控制元件檢視(Control View)

UI自動化樹的控制元件檢視簡化了輔助技術產品描述UI給終端使用者並幫助終端使用者與應用程式互動的任務,因為它與終端使用者感知的UI結構緊密對應。

控制元件檢視是原始檢視的一個子集。它包括原始檢視中的所有UI項,這些項被使用者理解為可互動,或對UI中的控制元件的邏輯結構起作用。

對UI邏輯結構有貢獻但本身不可互動的UI項例如有列表檢視的標題、工具列、選單和狀態列。

僅用於佈局或裝飾目的的非互動項不會在控制元件檢視中顯示。例如,一個本身不包含任何資訊,僅用於佈局對話方塊中的控制元件的面板。

控制元件檢視中可見的非互動項例如有包含資訊的圖形和對話方塊中的靜態文字。

控制元件檢視中包含的非互動項不能接收鍵盤焦點。

通過搜尋具有 IsControlElement 屬性設定為 true 的元素,或使用 ControlViewWalker 瀏覽樹,可以獲得控制元件檢視。

AutomationElement controlViewElementNode = TreeWalker.ControlViewWalker.GetFirstChild(AutomationElement.RootElement);

內容檢視(Content View)

UI自動化樹的內容檢視是控制元件檢視的一個子集。

它包含傳達使用者介面中真實資訊的UI項,包括可以接收鍵盤焦點的UI項以及一些不是UI項上的標籤的文字。例如,下拉下拉式方塊中的值將出現在內容檢視中,因為它們代表終端使用者正在使用的資訊。

在內容檢視中,下拉式方塊和列表框都被表示為一組UI項,其中可以選擇一個或多個項。

在內容檢視中,一個始終處於開啟狀態,而另一個可以展開和摺疊的事實是無關緊要的,因為它旨在顯示呈現給使用者的資料或內容。

通過搜尋具有 IsContentElement 屬性設定為 true 的元素,或使用 ContentViewWalker 瀏覽樹,可以獲得內容檢視。

AutomationElement ContentViewElementNode = TreeWalker.ContentViewWalker.GetFirstChild(AutomationElement.RootElement);

UI Automation elements(UI自動化元素)

UI自動化元素可以表示各種使用者介面元素,例如視窗、按鈕、文字方塊、核取方塊、列表框、選單等等。每個元素都有一個唯一的識別符號,稱為 AutomationID,它可以用來定位和操作元素。例如模擬使用者點選、輸入文字、選擇選項、獲取介面元素屬性等。

UI Automation properties(UI自動化屬性)

每個屬性都由一個數位和一個名稱標識。屬性的名稱僅用於偵錯和診斷。提供程式使用數位ID來標識傳入的屬性請求。然而,使用者端應用程式只使用 AutomationProperty 來標識它們希望檢索的屬性,AutomationProperty 封裝了數位和名稱。

表示特定屬性的 AutomationProperty 物件可作為各種類中的欄位使用。出於安全原因,UI自動化提供程式從 Uiautomationtypes.dll 中包含的一組單獨的類中獲取這些物件。

根據ID分組

以下表格按包含 AutomationPropertyIDs 的類對屬性進行了分類。

屬性的種類 使用者端從中獲取 ID 提供程式從中獲取 ID
所有元素共有的屬性(請參閱下表) AutomationElement AutomationElementIdentifiers
停靠視窗的位置 DockPattern DockPatternIdentifiers
可展開和摺疊的元素的狀態 ExpandCollapsePattern ExpandCollapsePatternIdentifiers
網格中某項的屬性 GridItemPattern GridItemPatternIdentifiers
網格的屬性 GridPattern GridPatternIdentifiers
具有多個檢視的元素的當前和支援的檢視 MultipleViewPattern MultipleViewPatternIdentifiers
在一定範圍的值內移動的元素(如滾軸)的屬性 RangeValuePattern RangeValuePatternIdentifiers
捲動視窗的屬性 ScrollPattern ScrollPatternIdentifiers
可選擇的某項(如列表中的某項)的狀態和容器 SelectionItemPattern SelectionItemPatternIdentifiers
包含選擇項的控制元件的屬性 SelectionPattern SelectionPatternIdentifiers
表中某項的列和行標題 TableItemPattern TableItemPatternIdentifiers
表的列和行標題以及方向 TablePattern TablePatternIdentifiers
切換控制元件的狀態 TogglePattern TogglePatternIdentifiers
可移動、旋轉、或調整大小的元素的功能 TransformPattern TransformPatternIdentifiers
具有值的元素的值和讀/寫功能 ValuePattern ValuePatternIdentifiers
視窗的功能和狀態 WindowPattern WindowPatternIdentifiers

根據類別分組

這裡只列舉根據標識分組,除此之外還有按顯示特徵分組,按元素型別分組,按互動型別分組,按對模式的支援分組等,詳見微軟官方檔案。

屬性識別符號 屬性存取
AutomationIdProperty AutomationId
ClassNameProperty ClassName
FrameworkIdProperty FrameworkId
LabeledByProperty LabeledBy
NameProperty Name
ProcessIdProperty ProcessId
RuntimeIdProperty GetRuntimeId
NativeWindowHandleProperty NativeWindowHandle

Control patterns(控制元件模式)

UI自動化使用控制元件模式來表示常見的控制元件行為。例如,您可以使用 Invoke 控制元件模式來處理可以呼叫的控制元件(如按鈕),並使用 Scroll 控制元件模式來處理帶有卷軸的控制元件(如列表框、列表檢視或下拉式方塊)。由於每個控制元件模式代表著一個獨立的功能,它們可以組合在一起描述特定控制元件支援的完整功能集。

控制元件模式支援定義控制元件中可用的離散功能所需的方法、屬性、事件和關係。

  • UI自動化元素與其父級、子級和同級之間的關係描述了元素在UI自動化樹中的結構。

  • 方法允許UI自動化使用者端操作控制元件。

  • 屬性和事件提供有關控制元件模式功能以及控制元件狀態的資訊。

控制元件模式與UI的關係類似於介面與元件物件模型(COM)物件的關係。在COM中,您可以查詢物件以瞭解它支援哪些介面,然後使用這些介面存取功能。在UI自動化中,UI自動化使用者端可以詢問控制元件支援哪些控制元件模式,然後通過支援的控制元件模式公開的屬性、方法、事件和結構與控制元件進行互動。例如,對於多行編輯框,UI自動化提供程式實現了 IScrollProvider。當用戶端知道 AutomationElement 支援 ScrollPattern 控制元件模式時,它可以使用該控制元件模式公開的屬性、方法和事件來操作控制元件或存取有關控制元件的資訊。

控制元件模式類 提供程式介面 說明
DockPattern IDockProvider 用於可在停靠容器中停靠的控制元件。 例如,工具列或工具調色盤。
ExpandCollapsePattern IExpandCollapseProvider 用於可展開或摺疊的控制元件。 例如,應用程式中的選單項,如 「檔案」 選單。
GridPattern IGridProvider 用於支援網格功能(如調整大小和移動到指定單元格)的控制元件。 例如 Windows 資源管理器中的大圖示檢視或 Microsoft Word 中的不帶檔頭的簡單表格。
GridItemPattern IGridItemProvider 用於在網格內具有單元格的控制元件。 單個單元格應支援 GridItem 模式。 例如 Microsoft Windows 資源管理器詳細資訊檢視中的每個單元格。
InvokePattern IInvokeProvider 用於可被呼叫的控制元件,如按鈕。
MultipleViewPattern IMultipleViewProvider 用於可在同一組資訊、資料或子級的多個表示形式之間切換的控制元件。 例如,在列表檢視控制元件中,資料可用於縮圖、磁貼、圖示、列表或詳細資訊檢視。
RangeValuePattern IRangeValueProvider 用於具有一系列可應用於該控制元件的值的控制元件。 例如,包含年份的微調框控制元件可能具有從 1900 到 2010 的年份範圍,而表示月份的另一個微調框控制元件則會具有從 1 到 12 的月份範圍。
ScrollPattern IScrollProvider 用於可捲動的控制元件。 例如,一個控制元件其所具有的卷軸在控制元件的可視區域中存在的資訊超過了可被顯示的資訊時,便處於活動狀態。
ScrollItemPattern IScrollItemProvider 用於一種控制元件,該控制元件具有可捲動列表中的各個項。 例如,一個列表控制元件,該控制元件具有捲動列表中的各個項,如下拉式方塊控制元件。
SelectionPattern ISelectionProvider 用於選擇容器控制元件。 例如,列表框和下拉式方塊。
SelectionItemPattern ISelectionItemProvider 用於選擇容器控制元件中的各個項,如列表框和下拉式方塊。
TablePattern ITableProvider 用於具有網格以及檔頭資訊的控制元件。 例如 Microsoft Excel 工作表。
TableItemPattern ITableItemProvider 用於表中的項。
TextPattern ITextProvider 用於可公開文字資訊的編輯控制元件和檔案。
TogglePattern IToggleProvider 用於在其中可切換狀態的控制元件。 例如,核取方塊和可選中的選單項。
TransformPattern ITransformProvider 用於可調整大小、移動和旋轉的控制元件。 Transform 控制元件模式通常用於設計器、表單、圖形編輯器和繪圖應用程式。
ValuePattern IValueProvider 允許使用者端在不支援某個值範圍的控制元件上獲取或設定值。 例如,日期時間選擇器。
WindowPattern IWindowProvider 向 Microsoft Windows 作業系統公開特定於視窗的資訊(一種基本概念)。 屬於視窗的控制元件範例是頂級應用程式視窗(Microsoft Word、Microsoft Windows 資源瀏覽器等)、多檔案介面 (MDI)子視窗和對話方塊。

UI Automation events(UI自動化事件)

Microsoft UI自動化事件是螢幕閱讀器和螢幕放大器等輔助技術的關鍵功能。這些UI自動化使用者端跟蹤由UI自動化提供程式觸發的事件,當UI中發生某些情況時,它們使用這些資訊通知終端使用者。

通過允許提供程式應用程式有選擇地觸發事件,根據是否有使用者端訂閱這些事件,或者如果沒有使用者端監聽任何事件,則可以完全不觸發事件,從而提高效率。

UI 自動化事件有以下型別。更詳細內容請閱讀微軟官方檔案。

事件 說明
屬性更改 當 UI 自動化元素上的某個屬性或控制元件模式更改時引發。 例如,如果使用者端需要監視應用程式的核取方塊控制元件,它可以註冊來偵聽 ToggleState 屬性上的屬性更改事件。 選中或取消選中該核取方塊控制元件時,提供程式會引發事件且使用者端會採取必要的操作。
元素操作 當來自終端使用者或程式設計活動的 UI 結果出現更改時引發;例如,單擊或通過 InvokePattern 呼叫一個按鈕。
結構更改 在 UI 自動化樹的結構更改時引發。 當桌面上有新 UI 項變得可見、隱藏或刪除時,結果便發生更改。
全域性桌面更改 當與使用者端相關的的全域性操作發生時引發,例如當焦點從一個元素轉換到另一個元素、或視窗關閉時。

結尾

文中只列舉了部分內容,更詳細內容請閱讀微軟官方檔案,檔案還是很詳細的,比較難受的地方就是範例程式碼太少,可能需要自己發掘了。

總的來說,我覺得一些簡單UI自動化測試執行起來應該是沒問題的,但是一些自定義控制元件,或者複雜操作流程的,可能就需要費些腦筋了,費腦筋了還不一定能搞定。

搞搞看吧。

參考連結

https://learn.microsoft.com/en-us/dotnet/framework/ui-automation/using-ui-automation-for-automated-testing