UIAutomation 自动化
Introduction
UI Automation是Microsoft .NET 3.0框架下提供的一種用于自動化測試的技術,是在MSAA基礎上建立的,MSAA就是Microsoft Active Accessibility。UI Automation在某些方面超過了MSAA,UI自動化提供了Windows Vista中,微軟Windows XP的全部功能,和Windows Server 2003。
在UI Automation中,所有的窗體、控件都表現為一個AutomationElement,?AutomationElement?中包含此控件或窗體的屬性,在實現自動化的過程中,我們通過其相關屬性進行對控件自動化操作。對于UI用戶界面來說,所有顯示在桌面上的UI,其實際是一個UI Tree,根節點是desktop。我們可以使用UI Spy或者是SPY++來獲得Window和Control的相關信息。在UI Automation里,根節點表示為AutomationElemnet.RootElement.?通過根節點,我們可以通過窗體或控件的Process Id、Process Name或者Window Name找到相應的子AutomationElement,例如Dialog、Button、TextBox、Checkbox等標準控件,通過控件所對應的Pattern進行相關的操作。
UI Automation structure
如下圖所示:
1.?在服務端由UIAutomationProvider.dll和UIAutomationTypes.dll提供。
???? 2.?在客戶端由UIAutomationClient.dll和UIAutomationTypes.dll提供。
???? 3.?UIAutomationCore.dll為UI自動化的核心部分,負責Server端和Client端的交互。
???? 4.?UIAUtomationClientSideProvides.dll為客戶端程序提供自動化支持。
使用UI Automation實現自動化測試--2
本文通過一個實例來介紹怎樣使用UI Automation實現軟件的自動化測試。
1. 首先建立一個待測試的winform程序,即UI Automation的服務端。
下面是button事件處理程序。
private?void?button1_Click(object?sender,?EventArgs?e)
{
?????int?i =?int.Parse(textBox1.Text);
?????int?j =?int.Parse(textBox2.Text);
???? textBox3.Text = (i + j).ToString();
}
2. 建立一個測試程序,做UI Automaion的客戶端。
添加引用:UIAutomationClient.dll 和 UIAutomationTypes.dll
??2using?System.Diagnostics;
??3using?System.Threading;
??4using?System.Windows.Automation.Provider;
??5using?System.Windows.Automation.Text;
??6using?System.Windows.Automation;
??7
??8namespace?UIAutomationTest
??9{
?10????class?Program
?11????{
?12????????static?void?Main(string[]?args)
?13????????{
?14????????????try
?15????????????{
?16????????????????Console.WriteLine("\nBegin?WinForm?UIAutomation?test?run\n");
?17????????????????//?launch?Form1?application
?18????????????????//?get?refernce?to?main?Form?control
?19????????????????//?get?references?to?user?controls
?20????????????????//?manipulate?application
?21????????????????//?check?resulting?state?and?determine?pass/fail
?22
?23????????????????Console.WriteLine("\nBegin?WinForm?UIAutomation?test?run\n");
?24????????????????Console.WriteLine("Launching?WinFormTest?application");
?25????????????????//啟動被測試的程序
?26????????????????Process?p?=?Process.Start(@"E:\Project\WinFormTest\WinFormTest\bin\Debug\WinFormTest.exe");
?27
?28????????????????//自動化根元素
?29????????????????AutomationElement?aeDeskTop?=?AutomationElement.RootElement;
?30
?31????????????????Thread.Sleep(2000);
?32????????????????AutomationElement?aeForm?=?AutomationElement.FromHandle(p.MainWindowHandle);
?33????????????????//獲得對主窗體對象的引用,該對象實際上就是?Form1?應用程序(方法一)
?34????????????????//if?(null?==?aeForm)
?35????????????????//{
?36????????????????//????Console.WriteLine("Can?not?find?the?WinFormTest?from.");
?37????????????????//}
?38
?39????????????????//獲得對主窗體對象的引用,該對象實際上就是?Form1?應用程序(方法二)
?40????????????????int?numWaits?=?0;
?41????????????????do
?42????????????????{
?43????????????????????Console.WriteLine("Looking?for?WinFormTest……");
?44????????????????????//查找第一個自動化元素
?45????????????????????aeForm?=?aeDeskTop.FindFirst(TreeScope.Children,?new?PropertyCondition(
?46????????????????????????AutomationElement.NameProperty,?"Form1"));
?47????????????????????++numWaits;
?48????????????????????Thread.Sleep(100);
?49????????????????}?while?(null?==?aeForm?&&?numWaits?<?50);
?50????????????????if?(null?==?aeForm)
?51????????????????????throw?new?NullReferenceException("Failed?to?find?WinFormTest.");
?52????????????????else
?53????????????????????Console.WriteLine("Found?it!");
?54
?55????????????????Console.WriteLine("Finding?all?user?controls");
?56????????????????//找到第一次出現的Button控件
?57????????????????AutomationElement?aeButton?=?aeForm.FindFirst(TreeScope.Children,
?58??????????????????new?PropertyCondition(AutomationElement.NameProperty,?"button1"));
?59
?60????????????????//找到所有的TextBox控件
?61????????????????AutomationElementCollection?aeAllTextBoxes?=?aeForm.FindAll(TreeScope.Children,
?62????????????????????new?PropertyCondition(AutomationElement.ControlTypeProperty,?ControlType.Edit));
?63
?64????????????????//?控件初始化的順序是先初始化后添加到控件
?65????????????????//?this.Controls.Add(this.textBox3);??????????????????
?66????????????????//?this.Controls.Add(this.textBox2);
?67????????????????//?this.Controls.Add(this.textBox1);
?68
?69????????????????AutomationElement?aeTextBox1?=?aeAllTextBoxes[2];
?70????????????????AutomationElement?aeTextBox2?=?aeAllTextBoxes[1];
?71????????????????AutomationElement?aeTextBox3?=?aeAllTextBoxes[0];
?72
?73????????????????Console.WriteLine("Settiing?input?to?'30'");
?74????????????????//通過ValuePattern設置TextBox1的值
?75????????????????ValuePattern?vpTextBox1?=?(ValuePattern)aeTextBox1.GetCurrentPattern(ValuePattern.Pattern);
?76????????????????vpTextBox1.SetValue("30");
?77????????????????Console.WriteLine("Settiing?input?to?'50'");
?78????????????????//通過ValuePattern設置TextBox2的值
?79????????????????ValuePattern?vpTextBox2?=?(ValuePattern)aeTextBox2.GetCurrentPattern(ValuePattern.Pattern);
?80????????????????vpTextBox2.SetValue("50");
?81????????????????Thread.Sleep(1500);
?82????????????????Console.WriteLine("Clickinig?on?button1?Button.");
?83????????????????//通過InvokePattern模擬點擊按鈕
?84????????????????InvokePattern?ipClickButton1?=?(InvokePattern)aeButton.GetCurrentPattern(InvokePattern.Pattern);
?85????????????????ipClickButton1.Invoke();
?86????????????????Thread.Sleep(1500);
?87
?88????????????????//驗證計算的結果與預期的結果是否相符合
?89????????????????Console.WriteLine("Checking?textBox3?for?'80'");
?90????????????????TextPattern?tpTextBox3?=?(TextPattern)aeTextBox3.GetCurrentPattern(TextPattern.Pattern);
?91????????????????string?result?=?tpTextBox3.DocumentRange.GetText(-1);//獲取textbox3中的值
?92????????????????//獲取textbox3中的值
?93????????????????//string?result?=?(string)aeTextBox2.GetCurrentPropertyValue(ValuePattern.ValueProperty);
?94????????????????if?("80"?==?result)
?95????????????????{
?96????????????????????Console.WriteLine("Found?it.");
?97????????????????????Console.WriteLine("TTest?scenario:?*PASS*");
?98????????????????}
?99????????????????else
100????????????????{
101????????????????????Console.WriteLine("Did?not?find?it.");
102????????????????????Console.WriteLine("Test?scenario:?*FAIL*");
103????????????????}
104
105????????????????Console.WriteLine("Close?application?in?5?seconds.");
106????????????????Thread.Sleep(5000);
107????????????????//實現關閉被測試程序
108????????????????WindowPattern?wpCloseForm?=?(WindowPattern)aeForm.GetCurrentPattern(WindowPattern.Pattern);
109????????????????wpCloseForm.Close();
110
111????????????????Console.WriteLine("\nEnd?test?run\n");
112????????????}
113????????????catch?(Exception?ex)
114????????????{
115????????????????Console.WriteLine("Fatal?error:?"?+?ex.Message);
116????????????}
117????????}
118????}
119}
120
使用UI Automation實現自動化測試--3
Chapter 3 ?UI Automation中的幾個重要屬性
Control Tree of the AutomationElement
在UI Automation控件樹中,根節點為Desktop window,?其他運行在用戶桌面的窗體都作為Desktop window的子節點。
如下圖所示:
Desktop window可通過AutomationElement.RootElement屬性獲取,子節點中的窗體或對話框可通過
AutomationElement.RootElement.FindAll(TreeScope.Descendants, condition)
或
AutomationElement.RootElement.FindFirt(TreeScope.Descendants, condition)來獲取.
AutomationElement property
在UI Automation中有如下幾個重要屬性:
注:PropertyCondition類是用來對相關屬性進行條件匹配,在控件樹中查找控件時,可以通過最佳匹配來找到相應的控件。
如下代碼列出了使用不同的屬性來構建PropertyCondition,通過PropertyCondition來查找控件樹中的控件.
public?class?PropertyConditions
????{
????????static?PropertyCondition?propertyCondition;
????????///?<summary>
????????///?Create?PropertyCondition?by?AutomationId
????????///?</summary>
????????///?<param?name="automationId">Control?AutomationId</param>
????????///?<returns>Return?PropertyCondition?instance</returns>
????????public?static?PropertyCondition?GetAutomationIdProperty(object?automationId)
????????{
????????????propertyCondition?=?new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId);
????????????return?propertyCondition;
????????}
????????///?<summary>
????????///?
????????///?</summary>
????????///?<param?name="controlType"></param>
????????///?<returns></returns>
????????public?static?PropertyCondition?GetControlTypeProperty(object?controlType)
????????{
????????????propertyCondition?=?new?PropertyCondition(AutomationElement.ControlTypeProperty,?controlType);
????????????return?propertyCondition;
????????}
????????///?<summary>
????????///?
????????///?</summary>
????????///?<param?name="controlName"></param>
????????///?<returns></returns>
????????public?static?PropertyCondition?GetNameProperty(object?controlName)
????????{
????????????propertyCondition?=?new?PropertyCondition(AutomationElement.NameProperty,?controlName);
????????????return?propertyCondition;
????????}
????????///?<summary>
????????///?Find?element?by?specific?PropertyCondition
????????///?</summary>
????????///?<param?name="condition">PropertyCondition?instance</param>
????????///?<returns>Target?automation?element</returns>
????????public?static?AutomationElement?FindElement(PropertyCondition?condition)
????????{
????????????return?AutomationElement.RootElement.FindFirst(TreeScope.Descendants,?condition);
????????}
????}
使用UI Automation實現自動化測試--4.1 (DockPattern)
DockPattern用于操作可停靠容器控件,我們最熟悉的VS2005/2008中的ToolBox,Solution Explorer都可以設置不同的DockPosition, 但是目前并不支持DockPattern,所以無法做為實例來講。使用DockPattern的前提為控件支持DockPattern。?DockPattern中的DockPosition有六個枚舉變量,即Bottom、Left、Right、Top、Fill和None。如果控件支持DockPattern,?則可以獲取相對應的DockPosition以及設置控件的DockPosition。
如下代碼是獲取控件的DockPattern、獲取控件當前的DockPosition以及設置控件的DockPosition。
#region?DockPattern?helper
????????///?<summary>
????????///?Get?DockPattern
????????///?</summary>
????????///?<param?name="element">AutomationElement?instance</param>
????????///?<returns>DockPattern?instance</returns>
????????public?static?DockPattern?GetDockPattern(AutomationElement?element)
????????{
????????????object?currentPattern;
????????????if?(!element.TryGetCurrentPattern(DockPattern.Pattern,?out?currentPattern))
????????????{
????????????????throw?new?Exception(string.Format("Element?with?AutomationId?'{0}'?and?Name?'{1}'?does?not?support?the?DockPattern.",
????????????????????element.Current.AutomationId,?element.Current.Name));
????????????}
????????????return?currentPattern?as?DockPattern;
????????}
????????///?<summary>
????????///?Get?DockPosition
????????///?</summary>
????????///?<param?name="element">AutomationElement?instance</param>
????????///?<returns>DockPosition?instance</returns>
????????public?static?DockPosition?GetDockPosition(AutomationElement?element)
????????{
????????????return?GetDockPattern(element).Current.DockPosition;
????????}
????????///?<summary>
????????///?Set?DockPosition
????????///?</summary>
????????///?<param?name="element">AutomationElement?instance</param>
????????public?static?void?SetDockPattern(AutomationElement?element,?DockPosition?dockPosition)
????????{
????????????GetDockPattern(element).SetDockPosition(dockPosition);
????????}
????????#endregion
使用UI Automation實現自動化測試--4.2 (ExpandCollapsePattern)
ExpandCollapsePattern
表示以可視方式進行展開(以顯示內容)和折疊(以隱藏內容)的控件。例如ComboBox控件支持ExpandCollapsePattern。
ExpandCollapsePattern有兩個主要方法:
Expand()方法:隱藏?AutomationElement?的全部子代節點、控件或內容。
Collapse()方法:顯示?AutomationElement?的全部子節點、控件或內容。
????? 以下代碼是用ExpandCollapsePattern來測試ComboBox控件的Expand和Collapse。
using?System;using?System.Text;using?System.Diagnostics;using?System.Threading;using?System.Windows.Automation;namespace?UIATest{????class?Program????{????????static?void?Main(string[]?args)????????{????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");????????????int?processId?=?process.Id;????????????AutomationElement?element?=?FindElementById(processId,?"comboBox1");????????????ExpandCollapsePattern?currentPattern?=?GetExpandCollapsePattern(element);????????????currentPattern.Expand();????????????Thread.Sleep(1000);????????????currentPattern.Collapse();????????}????????///?<summary>????????///?Get?the?automation?elemention?of?current?form.????????///?</summary>????????///?<param?name="processId">Process?Id</param>????????///?<returns>Target?element</returns>????????public?static?AutomationElement?FindWindowByProcessId(int?processId)????????{????????????AutomationElement?targetWindow?=?null;????????????int?count?=?0;????????????try????????????{????????????????Process?p?=?Process.GetProcessById(processId);????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);????????????????return?targetWindow;????????????}????????????catch?(Exception?ex)????????????{????????????????count++;????????????????StringBuilder?sb?=?new?StringBuilder();????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();????????????????if?(count?>?5)????????????????{????????????????????throw?new?InvalidProgramException(message,?ex);????????????????}????????????????else????????????????{????????????????????return?FindWindowByProcessId(processId);????????????????}????????????}????????}????????///?<summary>????????///?Get?the?automation?element?by?automation?Id.????????///?</summary>????????///?<param?name="windowName">Window?name</param>????????///?<param?name="automationId">Control?automation?Id</param>????????///?<returns>Automatin?element?searched?by?automation?Id</returns>????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)????????{????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));????????????return?tarFindElement;????????}????????ExpandCollapsePattern?helper????}}????? 以下代碼為被測程序的xaml文件:
?1<Window?x:Class="WpfApp.Window1"
?2????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
?3????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
?4????Title="Window1"?Height="219"?Width="353">
?5????<Grid>
?6????????<ComboBox?Name="comboBox1"?Height="23"?VerticalAlignment="Top"?Margin="94,58,0,0"?HorizontalAlignment="Left"?Width="119">
?7????????????<ComboBoxItem>kaden</ComboBoxItem>
?8????????????<ComboBoxItem>sam</ComboBoxItem>
?9????????</ComboBox>
10????</Grid>
11</Window>
?
使用UI Automation實現自動化測試--4.3 (InvokePattern)
InvokePattern
InvokePattern是UIA中最常用的Pattern之一,WPF和Winform中的button控件都支持InvokePattern。
對InvokePattern的Invoke()方法的調用應立即返回,沒有出現阻止情況。但是,此行為完全依賴于?Microsoft UI?自動化提供程序實現。在調用?Invoke()?會引起阻止問題(如Winform中的模式對話框,但是WPF中的對話框的處理方式和winform不同,所以可以使用Invoke()方法來操作WPF中的模式對話框,因為WPF中的模式對話框不會出現阻止的問題)的情況下,要調用此方法,則需要另起線程來操作。
using?System;
using?System.Text;
using?System.Diagnostics;
using?System.Threading;
using?System.Windows.Automation;
namespace?UIATest
{
????class?Program
????{
????????static?void?Main(string[]?args)
????????{
????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
????????????int?processId?=?process.Id;
????????????AutomationElement?element?=?FindElementById(processId,?"button1");
????????????InvokePattern?currentPattern?=?GetInvokePattern(element);
????????????currentPattern.Invoke();
????????}
????????///?<summary>
????????///?Get?the?automation?elemention?of?current?form.
????????///?</summary>
????????///?<param?name="processId">Process?Id</param>
????????///?<returns>Target?element</returns>
????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
????????{
????????????AutomationElement?targetWindow?=?null;
????????????int?count?=?0;
????????????try
????????????{
????????????????Process?p?=?Process.GetProcessById(processId);
????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
????????????????return?targetWindow;
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????count++;
????????????????StringBuilder?sb?=?new?StringBuilder();
????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
????????????????if?(count?>?5)
????????????????{
????????????????????throw?new?InvalidProgramException(message,?ex);
????????????????}
????????????????else
????????????????{
????????????????????return?FindWindowByProcessId(processId);
????????????????}
????????????}
????????}
????????///?<summary>
????????///?Get?the?automation?element?by?automation?Id.
????????///?</summary>
????????///?<param?name="windowName">Window?name</param>
????????///?<param?name="automationId">Control?automation?Id</param>
????????///?<returns>Automatin?element?searched?by?automation?Id</returns>
????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)
????????{
????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);
????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,
????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));
????????????return?tarFindElement;
????????}
????????#region?InvokePattern?helper
????????///?<summary>
????????///?Get?InvokePattern
????????///?</summary>
????????///?<param?name="element">AutomationElement?instance</param>
????????///?<returns>InvokePattern?instance</returns>
????????public?static?InvokePattern?GetInvokePattern(AutomationElement?element)
????????{
????????????object?currentPattern;
????????????if?(!element.TryGetCurrentPattern(InvokePattern.Pattern,?out?currentPattern))
????????????{
????????????????throw?new?Exception(string.Format("Element?with?AutomationId?'{0}'?and?Name?'{1}'?does?not?support?the?InvokePattern.",
????????????????????element.Current.AutomationId,?element.Current.Name));
????????????}
????????????return?currentPattern?as?InvokePattern;
????????}
????????#endregion
????}
}
被測程序xaml代碼如下:
<Window?x:Class="WpfApp.Window1"
????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
????Title="Window1"?Height="219"?Width="353">
????<Grid>
????????<Button?Height="23"?HorizontalAlignment="Left"?Click="button1_Click"?Margin="50,0,0,62"?Name="button1"?VerticalAlignment="Bottom"?Width="75">Button</Button>
????</Grid>
</Window>
對應的cs文件:
using?System;
using?System.Collections.Generic;
using?System.Linq;
using?System.Text;
using?System.Windows;
using?System.Windows.Controls;
using?System.Windows.Data;
using?System.Windows.Documents;
using?System.Windows.Input;
using?System.Windows.Media;
using?System.Windows.Media.Imaging;
using?System.Windows.Navigation;
using?System.Windows.Shapes;
namespace?WpfApp
{
????///?<summary>
????///?Interaction?logic?for?Window1.xaml
????///?</summary>
????public?partial?class?Window1?:?Window
????{
????????public?Window1()
????????{
????????????InitializeComponent();
????????}
????????private?void?button1_Click(object?sender,?RoutedEventArgs?e)
????????{
????????????MessageBox.Show("Use?InvokePattern?invoke?button.");
????????}
????}
}
????? 本文主要針對InvokePattern的Invoke方法來操作button控件。
使用UI Automation實現自動化測試--4.4 (ValuePattern)
ValuePattern是UI Automation中最常見的Pattern之一,Winform和WPF的TextBox控件都支持ValuePattern。
ValuePattern的一個重要的方法是SetValue,在允許調用?SetValue?之前,控件應將其?IsEnabledProperty?設置為?true?并將其?IsReadOnlyProperty?設置為?false。
通過ValuePattern的Current屬性可以獲得控件的value和IsReadOnly屬性。
實現?Value?控件模式時,請注意以下準則和約定:
如果任何項的值是可編輯的,則諸如?ListItem?和?TreeItem?等控件必須支持?ValuePattern,而不管控件的當前編輯模式如何。如果子項是可編輯的,則父控件還必須支持ValuePattern。
????下面的例子是通過ValuePattern來給TextBox設置和獲取值:
?1using?System;
?2using?System.Text;
?3using?System.Diagnostics;
?4using?System.Threading;
?5using?System.Windows.Automation;
?6
?7namespace?UIATest
?8{
?9????class?Program
10????{
11????????static?void?Main(string[]?args)
12????????{
13????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
14????????????int?processId?=?process.Id;
15????????????AutomationElement?element?=?FindElementById(processId,?"textBox1");
16????????????ValuePattern?currentPattern?=?GetValuePattern(element);
17????????????Console.WriteLine("Is?read?only:'{0}',?TextBox?text?is:'{1}'",?currentPattern.Current.IsReadOnly,?currentPattern.Current.Value);
18????????????currentPattern.SetValue("KadenKang");
19????????????Console.WriteLine("After?using?the?SetValue,?the?TextBox?value?is?'{0}'",?currentPattern.Current.Value);
20????????????
21????????}
22
23????????///?<summary>
24????????///?Get?the?automation?elemention?of?current?form.
25????????///?</summary>
26????????///?<param?name="processId">Process?Id</param>
27????????///?<returns>Target?element</returns>
28????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
29????????{
30????????????AutomationElement?targetWindow?=?null;
31????????????int?count?=?0;
32????????????try
33????????????{
34????????????????Process?p?=?Process.GetProcessById(processId);
35????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
36????????????????return?targetWindow;
37????????????}
38????????????catch?(Exception?ex)
39????????????{
40????????????????count++;
41????????????????StringBuilder?sb?=?new?StringBuilder();
42????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
43????????????????if?(count?>?5)
44????????????????{
45????????????????????throw?new?InvalidProgramException(message,?ex);
46????????????????}
47????????????????else
48????????????????{
49????????????????????return?FindWindowByProcessId(processId);
50????????????????}
51????????????}
52????????}
53
54????????///?<summary>
55????????///?Get?the?automation?element?by?automation?Id.
56????????///?</summary>
57????????///?<param?name="windowName">Window?name</param>
58????????///?<param?name="automationId">Control?automation?Id</param>
59????????///?<returns>Automatin?element?searched?by?automation?Id</returns>
60????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)
61????????{
62????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);
63????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,
64????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));
65????????????return?tarFindElement;
66????????}
67
68????????ValuePattern?helper
87????}
88}
89
下面的代碼是xaml設計:
1<Window?x:Class="WpfApp.Window1"
2????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4????Title="Window1"?Height="219"?Width="353">
5????<Grid>
6????????<TextBox?Height="23"?Margin="50,20,160,0"?Name="textBox1"?VerticalAlignment="Top"?MaxLength="5">textBox?text</TextBox>
7????</Grid>
8</Window>
9
?????本文通過簡單的實例介紹了UI Automation中的ValuePattern及其使用方法。
使用UI Automation實現自動化測試--4.5 (WindowPattern)
WindowPattern 控件模式用于支持在傳統的 圖形用戶界面 (GUI) 內提供基于基本窗口的功能的控件。必須實現此控件模式的控件的示例包括頂級應用程序窗口、多文檔界面 (MDI) 子窗口、大小可調的拆分窗格控件、模式對話框以及氣球狀幫助窗口。可以使用WindowPattern來對window進行操作,例如驗證window是否激活,是否最大化、最小化、正常模式以及關閉window等。
???? 下面的代碼演示了WindowPattern的使用方法:?
?1using?System;
?2using?System.Text;
?3using?System.Diagnostics;
?4using?System.Threading;
?5using?System.Windows.Automation;
?6
?7namespace?UIATest
?8{
?9????class?Program
10????{
11????????static?void?Main(string[]?args)
12????????{
13????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
14????????????int?processId?=?process.Id;
15????????????AutomationElement?element?=?FindWindowByProcessId(processId);
16????????????WindowPattern?currentPattern?=?GetWindowPattern(element);
17????????????
18????????????//Set?window?visual?state?to?Maximized
19????????????currentPattern.SetWindowVisualState(WindowVisualState.Maximized);
20????????????Thread.Sleep(1000);
21
22????????????//Set?window?visual?state?to?Normal
23????????????currentPattern.SetWindowVisualState(WindowVisualState.Normal);
24????????????Thread.Sleep(1000);
25
26????????????//Set?window?visual?state?to?Minimized
27????????????currentPattern.SetWindowVisualState(WindowVisualState.Minimized);
28????????????
29????????????//Close?window
30????????????currentPattern.Close();????????????
31????????}
32
33????????///?<summary>
34????????///?Get?the?automation?elemention?of?current?form.
35????????///?</summary>
36????????///?<param?name="processId">Process?Id</param>
37????????///?<returns>Target?element</returns>
38????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
39????????{
40????????????AutomationElement?targetWindow?=?null;
41????????????int?count?=?0;
42????????????try
43????????????{
44????????????????Process?p?=?Process.GetProcessById(processId);
45????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
46????????????????return?targetWindow;
47????????????}
48????????????catch?(Exception?ex)
49????????????{
50????????????????count++;
51????????????????StringBuilder?sb?=?new?StringBuilder();
52????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
53????????????????if?(count?>?5)
54????????????????{
55????????????????????throw?new?InvalidProgramException(message,?ex);
56????????????????}
57????????????????else
58????????????????{
59????????????????????return?FindWindowByProcessId(processId);
60????????????????}
61????????????}
62????????}
63
64????????WindowPattern?helper
83????}
84}
使用UI Automation實現自動化測試--4.6.1 (SelectionItemPattern)
SelectionItemPattern
支持SelectionItemPattern的控件有ListView、ListBox、RadioButton、GridView等。
?????如下代碼演示了使用SelectionItemPattern來操作RadioButton控件。
?1using?System;
?2using?System.Text;
?3using?System.Diagnostics;
?4using?System.Threading;
?5using?System.Windows.Automation;
?6
?7namespace?UIATest
?8{
?9????class?Program
10????{
11????????static?void?Main(string[]?args)
12????????{
13????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
14????????????int?processId?=?process.Id;
15
16????????????AutomationElement?element?=?FindElementById(processId,?"radioButton1");
17????????????SelectionItemPattern?selectionItemPattern?=?GetSelectionItemPattern(element);
18????????????selectionItemPattern.Select();
19????????}
20
21????????///?<summary>
22????????///?Get?the?automation?elemention?of?current?form.
23????????///?</summary>
24????????///?<param?name="processId">Process?Id</param>
25????????///?<returns>Target?element</returns>
26????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
27????????{
28????????????AutomationElement?targetWindow?=?null;
29????????????int?count?=?0;
30????????????try
31????????????{
32????????????????Process?p?=?Process.GetProcessById(processId);
33????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
34????????????????return?targetWindow;
35????????????}
36????????????catch?(Exception?ex)
37????????????{
38????????????????count++;
39????????????????StringBuilder?sb?=?new?StringBuilder();
40????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
41????????????????if?(count?>?5)
42????????????????{
43????????????????????throw?new?InvalidProgramException(message,?ex);
44????????????????}
45????????????????else
46????????????????{
47????????????????????return?FindWindowByProcessId(processId);
48????????????????}
49????????????}
50????????}
51
52
53????????///?<summary>
54????????///?Get?the?automation?element?by?automation?Id.
55????????///?</summary>
56????????///?<param?name="windowName">Window?name</param>
57????????///?<param?name="automationId">Control?automation?Id</param>
58????????///?<returns>Automatin?element?searched?by?automation?Id</returns>
59????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)
60????????{
61????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);
62????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,
63????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));
64????????????return?tarFindElement;
65????????}
66
67????????SelectItemPattern
86????}
87}
88
???? 以下代碼為XAML:
1<Window?x:Class="WpfApp.Window1"
2????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4????Title="Window1"?Height="219"?Width="353">
5????<Grid>
6????????<RadioButton?Height="16"?HorizontalAlignment="Right"?Margin="0,46,10,0"?Name="radioButton1"?VerticalAlignment="Top"?Width="120">RadioButton</RadioButton>
7????</Grid>
8</Window>
9
????本文簡單介紹了SelectionItemPattern以及使用SelectionItemPattern來操作RadioButton。
使用UI Automation實現自動化測試--4.6.2 (SelectItemPattern Demo)
?如下代碼演示了使用SelectionItemPattern來實現listview item 的多選操作:
??1using?System;
??2using?System.Text;
??3using?System.Diagnostics;
??4using?System.Threading;
??5using?System.Windows.Automation;
??6
??7namespace?UIATest
??8{
??9????class?Program
?10????{
?11????????static?void?Main(string[]?args)
?12????????{
?13????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
?14????????????int?processId?=?process.Id;
?15
?16????????????Thread.Sleep(1000);
?17????????????MutlSelect(new?int[]?{?0,?1?},?processId,?false);
?18????????}
?19
?20????????///?<summary>
?21????????///?Get?the?automation?elemention?of?current?form.
?22????????///?</summary>
?23????????///?<param?name="processId">Process?Id</param>
?24????????///?<returns>Target?element</returns>
?25????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
?26????????{
?27????????????AutomationElement?targetWindow?=?null;
?28????????????int?count?=?0;
?29????????????try
?30????????????{
?31????????????????Process?p?=?Process.GetProcessById(processId);
?32????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
?33????????????????return?targetWindow;
?34????????????}
?35????????????catch?(Exception?ex)
?36????????????{
?37????????????????count++;
?38????????????????StringBuilder?sb?=?new?StringBuilder();
?39????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
?40????????????????if?(count?>?5)
?41????????????????{
?42????????????????????throw?new?InvalidProgramException(message,?ex);
?43????????????????}
?44????????????????else
?45????????????????{
?46????????????????????return?FindWindowByProcessId(processId);
?47????????????????}
?48????????????}
?49????????}
?50
?51
?52????????///?<summary>
?53????????///?Get?the?automation?element?by?automation?Id.
?54????????///?</summary>
?55????????///?<param?name="windowName">Window?name</param>
?56????????///?<param?name="automationId">Control?automation?Id</param>
?57????????///?<returns>Automatin?element?searched?by?automation?Id</returns>
?58????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)
?59????????{
?60????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);
?61????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,
?62????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));
?63????????????return?tarFindElement;
?64????????}
?65????????
?66????????///?<summary>
?67????????///?Bulk?select?the?list?item
?68????????///?</summary>
?69????????///?<param?name="indexes">List?item?index?collection</param>
?70????????///?<param?name="processId">Application?process?Id</param>
?71????????///?<param?name="isSelectAll">Is?select?all?or?not</param>
?72????????public?static?void?MutlSelect(int[]?indexes,?int?processId,?bool?isSelectAll)
?73????????{
?74????????????AutomationElement?targetElement?=?FindElementById(processId,?"listView1");
?75
?76????????????AutomationElementCollection?rows?=
?77????????????????targetElement.FindAll(TreeScope.Descendants,
?78????????????????new?PropertyCondition(AutomationElement.ControlTypeProperty,?ControlType.ListItem));
?79
?80????????????object?multiSelect;
?81
?82????????????if?(isSelectAll)
?83????????????{
?84????????????????for?(int?i?=?1;?i?<?rows.Count?-?1;?i++)
?85????????????????{
?86????????????????????if?(rows[i].TryGetCurrentPattern(SelectionItemPattern.Pattern,?out?multiSelect))
?87????????????????????{
?88????????????????????????(multiSelect?as?SelectionItemPattern).AddToSelection();
?89????????????????????}
?90????????????????}
?91????????????}
?92????????????else
?93????????????{
?94????????????????if?(indexes.Length?>?0)
?95????????????????{
?96????????????????????for?(int?j?=?0;?j?<?indexes.Length;?j++)
?97????????????????????{
?98????????????????????????int?tempIndex?=?indexes[j];
?99????????????????????????if?(rows[tempIndex].TryGetCurrentPattern(SelectionItemPattern.Pattern,?out?multiSelect))
100????????????????????????{
101????????????????????????????(multiSelect?as?SelectionItemPattern).AddToSelection();
102????????????????????????}
103????????????????????}
104????????????????}
105????????????}
106????????}
107
108????????SelectItemPattern
127????}
128}
????? 如下代碼為對應的XAML:
?1<Window?x:Class="WpfApp.Window2"
?2????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
?3????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
?4????Title="Window2"?Height="412"?Width="585">
?5????<Grid>
?6????????<ListView?Margin="2,97,0,163"?Name="listView1">
?7????????????<ListViewItem>Kaden</ListViewItem>
?8????????????<ListViewItem>KangYi</ListViewItem>
?9????????????<ListViewItem>John</ListViewItem>
10????????</ListView>
11????</Grid>
12</Window>
13
使用UI Automation實現自動化測試--4.7 (TogglePattern)
TogglePattern
支持TogglePattern的控件有CheckBox,TreeView中的button控件等。
Toggle方法用于操作可以循環通過的一組狀態并在設置后保持某種狀態。
Current屬性中的ToggleState有如下三種狀態:
????如下代碼演示了使用TogglePattern來操作CheckBox控件。
?1using?System;
?2using?System.Text;
?3using?System.Diagnostics;
?4using?System.Threading;
?5using?System.Windows.Automation;
?6
?7namespace?UIATest
?8{
?9????class?Program
10????{
11????????static?void?Main(string[]?args)
12????????{
13????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
14????????????int?processId?=?process.Id;
15
16????????????Thread.Sleep(1000);
17????????????AutomationElement?element?=?FindElementById(processId,?"checkBox1");
18????????????TogglePattern?togglePattern?=?GetTogglePattern(element);
19????????????togglePattern.Toggle();
20????????}
21
22????????///?<summary>
23????????///?Get?the?automation?elemention?of?current?form.
24????????///?</summary>
25????????///?<param?name="processId">Process?Id</param>
26????????///?<returns>Target?element</returns>
27????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
28????????{
29????????????AutomationElement?targetWindow?=?null;
30????????????int?count?=?0;
31????????????try
32????????????{
33????????????????Process?p?=?Process.GetProcessById(processId);
34????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
35????????????????return?targetWindow;
36????????????}
37????????????catch?(Exception?ex)
38????????????{
39????????????????count++;
40????????????????StringBuilder?sb?=?new?StringBuilder();
41????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
42????????????????if?(count?>?5)
43????????????????{
44????????????????????throw?new?InvalidProgramException(message,?ex);
45????????????????}
46????????????????else
47????????????????{
48????????????????????return?FindWindowByProcessId(processId);
49????????????????}
50????????????}
51????????}
52
53????????///?<summary>
54????????///?Get?the?automation?element?by?automation?Id.
55????????///?</summary>
56????????///?<param?name="windowName">Window?name</param>
57????????///?<param?name="automationId">Control?automation?Id</param>
58????????///?<returns>Automatin?element?searched?by?automation?Id</returns>
59????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)
60????????{
61????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);
62????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,
63????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));
64????????????return?tarFindElement;
65????????}
66
67????????TogglePattern?helper
83????}
84}
85
???? 如下代碼為對應的XAML:
1<Window?x:Class="WpfApp.Window1"
2????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4????Title="Window1"?Height="219"?Width="353">
5????<Grid>
6????????<CheckBox?HorizontalAlignment="Right"?Margin="0,75,10,89"?Name="checkBox1"?Width="120">CheckBox</CheckBox>
7????</Grid>
8</Window>
使用UI Automation實現自動化測試--4.8 (GridPattern)
GridPattern
支持GridPattern的最常見的控件為GridView,?在WPF中使用ListView和GridView組合即可得到相應的GridView。
GridPattern的方法
GetItem:此方法有兩個參數,即DataGrid的Row和Column。
通過GridPattern的GetItem方法可以獲取DataGrid中的某個確定的單元格,進而對單元進行操作。
對單元格的操作主要有以下幾個方面:
GridPattern的屬性
GridPattern的Current屬性中有如下兩個屬性:
下面我們通過一個實例來演示自動化測試中如何使用GridPattern來測試GridView的方法:
?1using?System;
?2using?System.Text;
?3using?System.Diagnostics;
?4using?System.Threading;
?5using?System.Windows.Automation;
?6
?7namespace?UIATest
?8{
?9????class?Program
10????{
11????????static?void?Main(string[]?args)
12????????{
13????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
14????????????int?processId?=?process.Id;
15????????????Thread.Sleep(1000);
16
17????????????GridPattern?Test
30????????}
31
32????????///?<summary>
33????????///?Get?the?automation?elemention?of?current?form.
34????????///?</summary>
35????????///?<param?name="processId">Process?Id</param>
36????????///?<returns>Target?element</returns>
37????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
38????????{
39????????????AutomationElement?targetWindow?=?null;
40????????????int?count?=?0;
41????????????try
42????????????{
43????????????????Process?p?=?Process.GetProcessById(processId);
44????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
45????????????????return?targetWindow;
46????????????}
47????????????catch?(Exception?ex)
48????????????{
49????????????????count++;
50????????????????StringBuilder?sb?=?new?StringBuilder();
51????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
52????????????????if?(count?>?5)
53????????????????{
54????????????????????throw?new?InvalidProgramException(message,?ex);
55????????????????}
56????????????????else
57????????????????{
58????????????????????return?FindWindowByProcessId(processId);
59????????????????}
60????????????}
61????????}
62
63????????///?<summary>
64????????///?Get?the?automation?element?by?automation?Id.
65????????///?</summary>
66????????///?<param?name="windowName">Window?name</param>
67????????///?<param?name="automationId">Control?automation?Id</param>
68????????///?<returns>Automatin?element?searched?by?automation?Id</returns>
69????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)
70????????{
71????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);
72????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,
73????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));
74????????????return?tarFindElement;
75????????}
76
77????????GridPattern?helper
95????}
96}
97
????對應的XAML代碼如下:
?1<Window?x:Class="WpfApp.GridView"
?2????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
?3????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
?4????Title="GridView"?Height="426"?Width="558">
?5????<Grid>
?6????????<!--將鼠標放在方框的邊緣點擊就會產生相應的分割線生成Grid.RowDefinitions-->
?7????????<Grid.RowDefinitions>
?8????????????<!--Auto,實際作用就是取實際控件所需的最小值;值為*或N*,實際作用就是取盡可能大的值;數字,絕對尺寸-->
?9????????????<RowDefinition?Height="*"?/>
10????????????<RowDefinition?Height="auto"?MinHeight="95"?/>
11????????????<RowDefinition?Height="22"?/>
12????????</Grid.RowDefinitions>
13????????<ListView?Name="listview1"?MinWidth="280"?Grid.RowSpan="2"?MouseMove="listview1_MouseMove">
14????????????<ListView.View>
15????????????????<GridView?x:Name="gridView1">
16????????????????????<GridViewColumn?Header="EmployeeID"?DisplayMemberBinding="{Binding?Path=EmployeeID}"></GridViewColumn>
17????????????????????<GridViewColumn?Header="FirstName"?DisplayMemberBinding="{Binding?Path=FirstName}"></GridViewColumn>
18????????????????????<GridViewColumn?Header="LastName"?DisplayMemberBinding="{Binding?Path=LastName}"></GridViewColumn>
19????????????????????<GridViewColumn?Header="Address"?DisplayMemberBinding="{Binding?Path=Address}"></GridViewColumn>
20????????????????</GridView>
21????????????</ListView.View>
22????????</ListView>
23????</Grid>
24
25</Window>
26
????GridView窗體后臺代碼如下:
?1using?System;
?2using?System.Collections.Generic;
?3using?System.Linq;
?4using?System.Text;
?5using?System.Windows;
?6using?System.Windows.Controls;
?7using?System.Windows.Data;
?8using?System.Windows.Documents;
?9using?System.Windows.Input;
10using?System.Windows.Media;
11using?System.Windows.Media.Imaging;
12using?System.Windows.Shapes;
13using?System.Data.SqlClient;
14using?System.Data;
15
16namespace?WpfApp
17{
18????///?<summary>
19????///?Interaction?logic?for?GridView.xaml
20????///?</summary>
21????public?partial?class?GridView?:?Window
22????{
23????????public?GridView()
24????????{
25????????????InitializeComponent();
26????????????getData();
27????????}
28????????SqlDataAdapter?sda;
29????????DataTable?dt;
30????????void?getData()
31????????{
32????????????//Northwind?database?download?path:http://download.csdn.net/down/845087/beyondchina123
33????????????//init?sqlconnection
34????????????SqlConnectionStringBuilder?connbuilder?=?new?SqlConnectionStringBuilder();
35????????????connbuilder.DataSource?=?".";//本地服務器
36????????????connbuilder.IntegratedSecurity?=?true;//Windows集成驗證
37????????????connbuilder.InitialCatalog?=?"Northwind";//數據庫為Northwind
38????????????SqlConnection?conn?=?new?SqlConnection(connbuilder.ConnectionString);
39????????????sda?=?new?SqlDataAdapter("select?EmployeeID,FirstName,LastName,Address?from?Employees?",?conn);
40????????????SqlCommandBuilder?commbuilder?=?new?SqlCommandBuilder(sda);
41????????????dt?=?new?DataTable();
42????????????sda.Fill(dt);
43????????????listview1.ItemsSource?=?dt.DefaultView;
44????????}
45??????}
46}
47
48
?????本文主要簡單介紹了GridPattern以及GridPattern在測試中是使用方法。
使用UI Automation實現自動化測試--4.9 (ScrollPattern)
ScrollPattern
ScrollPattern是用來操作控件的滾動條,目前支持ScrollPattern的控件有ListBox,listView,GridView,TreeView.
ScrollPattern主要方法
ScrollPattern屬性
下面我們通過一個實例來演示自動化測試中如何使用ScrollPattern來測試GridView中滾動條的方法:
??1using?System;
??2using?System.Text;
??3using?System.Diagnostics;
??4using?System.Threading;
??5using?System.Windows.Automation;
??6
??7namespace?UIATest
??8{
??9????class?Program
?10????{
?11????????static?void?Main(string[]?args)
?12????????{
?13????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
?14????????????int?processId?=?process.Id;
?15????????????Thread.Sleep(1000);
?16
?17????????????ScrollPattern
?31????????????
?32????????}
?33
?34????????///?<summary>
?35????????///?Get?the?automation?elemention?of?current?form.
?36????????///?</summary>
?37????????///?<param?name="processId">Process?Id</param>
?38????????///?<returns>Target?element</returns>
?39????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
?40????????{
?41????????????AutomationElement?targetWindow?=?null;
?42????????????int?count?=?0;
?43????????????try
?44????????????{
?45????????????????Process?p?=?Process.GetProcessById(processId);
?46????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
?47????????????????return?targetWindow;
?48????????????}
?49????????????catch?(Exception?ex)
?50????????????{
?51????????????????count++;
?52????????????????StringBuilder?sb?=?new?StringBuilder();
?53????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
?54????????????????if?(count?>?5)
?55????????????????{
?56????????????????????throw?new?InvalidProgramException(message,?ex);
?57????????????????}
?58????????????????else
?59????????????????{
?60????????????????????return?FindWindowByProcessId(processId);
?61????????????????}
?62????????????}
?63????????}
?64
?65
?66????????///?<summary>
?67????????///?Get?the?automation?element?by?automation?Id.
?68????????///?</summary>
?69????????///?<param?name="windowName">Window?name</param>
?70????????///?<param?name="automationId">Control?automation?Id</param>
?71????????///?<returns>Automatin?element?searched?by?automation?Id</returns>
?72????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)
?73????????{
?74????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);
?75????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,
?76????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));
?77????????????return?tarFindElement;
?78????????}
?79
?80????????GetScrollPattern?helper
?98????}
?99}
100
???XAML源碼:
?1<Window?x:Class="WpfApp.GridView"
?2????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
?3????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
?4????Title="GridView"?Height="280"?Width="467">
?5????<Grid>
?6????????<!--將鼠標放在方框的邊緣點擊就會產生相應的分割線生成Grid.RowDefinitions-->
?7????????<Grid.RowDefinitions>
?8????????????<!--Auto,實際作用就是取實際控件所需的最小值;值為*或N*,實際作用就是取盡可能大的值;數字,絕對尺寸-->
?9????????????<RowDefinition?Height="*"?/>
10????????????<RowDefinition?Height="auto"?MinHeight="95"?/>
11????????????<RowDefinition?Height="22"?/>
12????????</Grid.RowDefinitions>
13????????<ListView?Name="listview1"?MinWidth="280"?Grid.RowSpan="2"?MouseMove="listview1_MouseMove">
14????????????<ListView.View>
15????????????????<GridView?x:Name="gridView1">
16????????????????????<GridViewColumn?Header="EmployeeID"?DisplayMemberBinding="{Binding?Path=EmployeeID}"></GridViewColumn>
17????????????????????<GridViewColumn?Header="FirstName"?DisplayMemberBinding="{Binding?Path=FirstName}"></GridViewColumn>
18????????????????????<GridViewColumn?Header="LastName"?DisplayMemberBinding="{Binding?Path=LastName}"></GridViewColumn>
19????????????????????<GridViewColumn?Header="Address"?DisplayMemberBinding="{Binding?Path=Address}"></GridViewColumn>
20????????????????</GridView>
21????????????</ListView.View>
22????????</ListView>
23????????<!--Grid.Row="1"用來設置WrapPanel及Button應該在父容器的什么位置-->
24????</Grid>
25
26</Window>
?????? 后臺CS源碼:
?1using?System;
?2using?System.Collections.Generic;
?3using?System.Linq;
?4using?System.Text;
?5using?System.Windows;
?6using?System.Windows.Controls;
?7using?System.Windows.Data;
?8using?System.Windows.Documents;
?9using?System.Windows.Input;
10using?System.Windows.Media;
11using?System.Windows.Media.Imaging;
12using?System.Windows.Shapes;
13using?System.Data.SqlClient;
14using?System.Data;
15
16namespace?WpfApp
17{
18????///?<summary>
19????///?Interaction?logic?for?GridView.xaml
20????///?</summary>
21????public?partial?class?GridView?:?Window
22????{
23????????public?GridView()
24????????{
25????????????InitializeComponent();
26????????????getData();
27????????}
28????????SqlDataAdapter?sda;
29????????DataTable?dt;
30????????void?getData()
31????????{
32????????????//init?sqlconnection
33????????????SqlConnectionStringBuilder?connbuilder?=?new?SqlConnectionStringBuilder();
34????????????connbuilder.DataSource?=?".";//本地服務器
35????????????connbuilder.IntegratedSecurity?=?true;//Windows集成驗證
36????????????connbuilder.InitialCatalog?=?"TestDB";//數據庫為Northwind
37????????????SqlConnection?conn?=?new?SqlConnection(connbuilder.ConnectionString);
38????????????sda?=?new?SqlDataAdapter("select?EmployeeID,FirstName,LastName,Address?from?Employees?",?conn);
39????????????SqlCommandBuilder?commbuilder?=?new?SqlCommandBuilder(sda);
40????????????//sda.UpdateCommand?=?commbuilder.GetUpdateCommand();
41????????????dt?=?new?DataTable();
42????????????//sda.AcceptChangesDuringUpdate?=?true;
43????????????sda.Fill(dt);
44????????????listview1.ItemsSource?=?dt.DefaultView;
45????????}
46????}
47}
48
49
?????? 數據庫及數據庫表源碼:
?1USE?[master]
?2GO
?3/******?Object:??Database?TestDB????Script?Date:?10/17/2009?16:08:09?******/
?4IF??EXISTS?(SELECT?name?FROM?sys.databases?WHERE?name?=?N'TestDB')
?5DROP?DATABASE?[TestDB]
?6CREATE?DATABASE?TestDB?ON??PRIMARY?
?7(?NAME?=?N'TestDB',?FILENAME?=?N'C:\TestDB.mdf'?,?SIZE?=?2688KB?,?MAXSIZE?=?UNLIMITED,?FILEGROWTH?=?80KB?)
?8?LOG?ON?
?9(?NAME?=?N'TestDB_log',?FILENAME?=?N'C:\TestDB.ldf'?,?SIZE?=?1024KB?,?MAXSIZE?=?UNLIMITED,?FILEGROWTH?=?10%)
10GO
11
12use?TestDB
13
14CREATE?TABLE?[dbo].[Employees](
15????[EmployeeID]?[int]?IDENTITY(1,1)?primary?key?NOT?NULL,
16????[LastName]?[varchar](20)?NOT?NULL,
17????[FirstName]?[varchar](10)?NOT?NULL,
18????[Address]?[varchar](60)?NULL
19)?
20
21GO
22truncate?table?employees
23declare?@i?int
24set?@i?=?1
25while?@i<25
26begin
27
28insert?into?Employees
29(
30???LastName,
31???FirstName,
32???[Address]
33)?
34values
35('Kaden'+cast(@i?as?varchar),?'Kang'+cast(@i?as?varchar),?'Nanjing,?Jiangsu,?China'+cast(@i?as?varchar))
36set?@i=@i+1
37end
38
39
????????本文簡單介紹了ScrollPattern以及使用ScrollPattern來操作垂直水平滾動條。
總結
以上是生活随笔為你收集整理的UIAutomation 自动化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 黑龙的cd是多久(黑龙cd怎么算)
- 下一篇: Emgu介绍