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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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中有如下几个重要属性:
- AutomationIdProperty: 通过AutomationId来查找AutomationElement。
- NameProperty:通过控件的Name属性来查找AutomationElement。
- ControlType:通过控件的类型来查找AutomationElement
- AutomationId: 唯一地标识自动化元素,将其与同级相区分。
- Name: WPF 按钮的Content 属性、Win32 按钮的Caption 属性以及 HTML 图像的ALT 属性都映射到 UI 自动化视图中的同一个属性 Name。
注:PropertyCondition类是用来对相关属性进行条件匹配,在控件树中查找控件时,可以通过最佳匹配来找到相应的控件。
如下代码列出了使用不同的属性来构建PropertyCondition,通过PropertyCondition来查找控件树中的控件.
public class PropertyConditions
{
static PropertyCondition propertyCondition;
///
/// Create PropertyCondition by AutomationId
///
/// Control AutomationId
///
public static PropertyCondition GetAutomationIdProperty(object automationId)
{
propertyCondition = new PropertyCondition(AutomationElement.AutomationIdProperty, automationId);
return propertyCondition;
}
///
///
///
///
///
public static PropertyCondition GetControlTypeProperty(object controlType)
{
propertyCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, controlType);
return propertyCondition;
}
///
///
///
///
///
public static PropertyCondition GetNameProperty(object controlName)
{
propertyCondition = new PropertyCondition(AutomationElement.NameProperty, controlName);
return propertyCondition;
}
///
/// Find element by specific PropertyCondition
///
/// PropertyCondition instance
///
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
///
/// Get DockPattern
///
/// AutomationElement instance
///
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;
}
///
/// Get DockPosition
///
/// AutomationElement instance
///
public static DockPosition GetDockPosition(AutomationElement element)
{
return GetDockPattern(element).Current.DockPosition;
}
///
/// Set DockPosition
///
/// AutomationElement instance
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。
以下代码为被测程序的xaml文件:
1
2
3
4
5
6
7
8
9
10
11
使用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();
}
///
/// Get the automation elemention of current form.
///
/// Process Id
///
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);
}
}
}
///
/// Get the automation element by automation Id.
///
/// Window name
/// Control automation Id
///
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
///
/// Get InvokePattern
///
/// AutomationElement instance
///
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代码如下:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="219" Width="353">
对应的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
{
///
/// Interaction logic for Window1.xaml
///
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 ///
24 /// Get the automation elemention of current form.
25 ///
26 /// Process Id
27 ///
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 ///
55 /// Get the automation element by automation Id.
56 ///
57 /// Window name
58 /// Control automation Id
59 ///
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
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="Window1" Height="219" Width="353">
5
6
7
8
9
本文通过简单的实例介绍了UI Automation中的ValuePattern及其使用方法。
使用UI Automation实现自动化测试--4.5 (WindowPattern)
WindowPattern 控件模式用于支持在传统的 图形用户界面 (GUI) 内提供基于基本窗口的功能的控件。必须实现此控件模式的控件的示例包括顶级应用程序窗口、多文档界面 (MDI) 子窗口、大小可调的拆分窗格控件、模式对话框以及气球状帮助窗口。可以使用WindowPattern来对window进行操作,例如验证window是否激活,是否最大化、最小化、正常模式以及关闭window等。
下面的代码演示了WindowPattern的使用方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
83
84
使用UI Automation实现自动化测试--4.6.1 (SelectionItemPattern)
SelectionItemPattern
支持SelectionItemPattern的控件有ListView、ListBox、RadioButton、GridView等。
- 1. SelectionItemPattern的三个重要方法:
- 1. AddToSelection:将当前元素添加到所选项的集合。
- 2. RemoveFromSelection: 从选定项的集合中移除当前元素。
- 3. Select: 取消所有已选中的项,然后选择当前元素。
- 2. SelectionItemPattern的Current属性可通过Current属性的IsSelected属性来判断AutomationElement是否被selected.
如下代码演示了使用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 ///
22 /// Get the automation elemention of current form.
23 ///
24 /// Process Id
25 ///
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 ///
54 /// Get the automation element by automation Id.
55 ///
56 /// Window name
57 /// Control automation Id
58 ///
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
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="Window1" Height="219" Width="353">
5
6
7
8
9
本文简单介绍了SelectionItemPattern以及使用SelectionItemPattern来操作RadioButton。
使用UI Automation实现自动化测试--4.6.2 (SelectItemPattern Demo)
如下代码演示了使用SelectionItemPattern来实现listview item 的多选操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
127
128
如下代码为对应的XAML:
1
2
3
4
5
6
7
8
9
10
11
12
13
使用UI Automation实现自动化测试--4.7 (TogglePattern)
TogglePattern
支持TogglePattern的控件有CheckBox,TreeView中的button控件等。
- 1. TogglePattern的方法
Toggle方法用于操作可以循环通过的一组状态并在设置后保持某种状态。
- 2. TogglePattern属性
Current属性中的ToggleState有如下三种状态:
- 1. On
- 2. Off
- 3. Indeterminate
如下代码演示了使用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 ///
23 /// Get the automation elemention of current form.
24 ///
25 /// Process Id
26 ///
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 ///
54 /// Get the automation element by automation Id.
55 ///
56 /// Window name
57 /// Control automation Id
58 ///
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
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="Window1" Height="219" Width="353">
5
6
7
8
使用UI Automation实现自动化测试--4.8 (GridPattern)
GridPattern
支持GridPattern的最常见的控件为GridView, 在WPF中使用ListView和GridView组合即可得到相应的GridView。
GridPattern的方法
GetItem:此方法有两个参数,即DataGrid的Row和Column。
通过GridPattern的GetItem方法可以获取DataGrid中的某个确定的单元格,进而对单元进行操作。
对单元格的操作主要有以下几个方面:
- 1. 编辑单元个中的数据。
- 2. 获取单元格中的数据。
- 3. 获取单元格中嵌套的AutomationElement(一般使用与自定义控件中)。
GridPattern的属性
GridPattern的Current属性中有如下两个属性:
- 1. RowCount属性:GridPattern二维表格的行数。
- 2. ColumnCount属性:GridPattern二维表格列数。
下面我们通过一个实例来演示自动化测试中如何使用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 ///
33 /// Get the automation elemention of current form.
34 ///
35 /// Process Id
36 ///
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 ///
64 /// Get the automation element by automation Id.
65 ///
66 /// Window name
67 /// Control automation Id
68 ///
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
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="GridView" Height="426" Width="558">
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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 ///
19 /// Interaction logic for GridView.xaml
20 ///
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主要方法
- 1. Scroll 水平和垂直滚动内容区域的可见区域滚动, Scroll有两个参数,其类型为ScrollAmount枚举类型。
- 2. ScrollHorizontal 按指定的 ScrollAmount 水平滚动内容区域的当前可见区域滚动。
- 3. ScrollVertical 按指定的 ScrollAmount 垂直滚动内容区域的当前可见区域滚动。
ScrollPattern属性
- VerticallyScrollable 属性用于判定是否可以垂直滚动。
- HorizontallyScrollable 属性用于判定是否可以水平滚动。
- HorizontalScrollPercent 获取当前水平滚动条的位置。
- VerticalScrollPercent 获取当前垂直滚动条的位置。
下面我们通过一个实例来演示自动化测试中如何使用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 ///
35 /// Get the automation elemention of current form.
36 ///
37 /// Process Id
38 ///
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 ///
67 /// Get the automation element by automation Id.
68 ///
69 /// Window name
70 /// Control automation Id
71 ///
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
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="GridView" Height="280" Width="467">
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
后台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 ///
19 /// Interaction logic for GridView.xaml
20 ///
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来操作垂直水平滚动条。