失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > .Net软件UI界面测试自动化--UIAutomation技术

.Net软件UI界面测试自动化--UIAutomation技术

时间:2018-09-15 21:26:17

相关推荐

.Net软件UI界面测试自动化--UIAutomation技术

在目前进行软件测试时,都或多或少的引入了自动化测试的概念,而且市面上也有好多软件自动化方面相关的工具,比如QTP,比如LoadRunner,但是这些工具要么售价不菲,要么对某些方面功能支持的不够全面,那么我们在引入软件自动化测试时,都需要考虑哪些方面呢?当然是最符合自己项目的工具最合适,同时费用也比较低,那么除了市面上这些商业软件外,还有没有哪些方法可以自己动手来做软件的自动化测试呢?答案是肯定的.

本文将介绍实现软件自动化测试其中一种测试方法------UIAutomation技术,当然,此种方法仅限于对.Net软件使用.

反射技术具体是什么原理,本文将不做任何介绍,大家可以去网上搜索一下,有很多这方面的文章介绍,本文只介绍如何使用UIAutomation技术进行.NET软件的UI界面的自动化测试.

废话少说,多做实事!(本文所有代码均在VS环境下测试通过)

一. 创建待测试程序

1. 启动VS,建立一个C#的WinForm工程,并将工程文件名命名为AUT(Application Under Test)

2. 创建的Form上的按钮布局,如下图所示

3. 一个菜单(包含一个以及菜单File以及一个二级菜单Exit),一个TextBox,一个ComboBox,一个Button以及一个ListBox

private System.Windows.Forms.MenuStrip menuStrip1;

private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;

private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;

private System.Windows.Forms.TextBox textBox1;

private System.boBox comboBox1;

private System.Windows.Forms.Button button1;

private System.Windows.Forms.ListBox listBox1;

4. 给Button按钮添加一个消息响应函数

private void button1_Click(object sender, EventArgs e)

{

string tb = textBox1.Text;

string cb = comboBox1.Text;

if (tb == cb)

{

listBox1.Items.Add("Result is a tie");

}

else if (tb == "paper" && cb == "rock" ||

tb == "rock" && cb == "scissors" ||

tb == "scissors" && cb == "paper")

{

listBox1.Items.Add("The TextBox wins");

}

else

{

listBox1.Items.Add("The ComboBox wins");

}

}

5. 给Exit菜单添加一个消息响应函数

private void exitToolStripMenuItem_Click(object sender, EventArgs e)

{

Application.Exit();

}

6.给ComboBox控件添加三个Item,分别为paper,rock,scissions

7. 编译待测试程序,生成文件名为AUT.exe的待测试程序

二. 创建测试程序

1. 启动VS,创建一个C#控制台程序,并命名为AutomationUITest

2. 在引用中添加以下三个类: UIAutomationClient, UIAutomationClientsideProviders以及UIAutomationTypes

3. 在工程中添加以下using语句

using System;

using System.Windows.Automation;

using System.Threading;

using System.Diagnostics;

using System.IO;

4. 定义启动测试程序以及获取窗体句柄的函数

///<summary>

///根据传入的路径启动相应的可执行程序,并返回进程ID

///</summary>

public static Int32 StartExe(string strExePath)

{

if (null == strExePath)

{

return 0;

}

Process ps = Process.Start(strExePath);

Thread.Sleep(3000);

return ps.Id;

}

///<summary>

///根据进程ID,查找相应窗体,并返回窗体句柄

///</summary>

public static AutomationElement GetWindowHandle(Int32 pid, int iWaitSecond)

{

AutomationElement targetWindow = null;

int iWaitTime = 0;

try

{

Process ps = Process.GetProcessById(pid);

targetWindow = AutomationElement.FromHandle(ps.MainWindowHandle);

while (null == targetWindow)

{

if (iWaitTime > iWaitSecond)

{

break;

}

Thread.Sleep(500);

targetWindow = AutomationElement.FromHandle(ps.MainWindowHandle);

}

return targetWindow;

}

catch (System.Exception ex)

{

string msg = "没有找到指定的窗口,请确认窗口已经启动!";

throw new InvalidProgramException(msg, ex);

}

}

5. 定义操作TextBox的相关函数\

///<summary>

///根据窗口句柄以及TextEdit的AutomationID,返回TextEdit句柄

///</summary>

public static AutomationElement GetTextEditHandle(AutomationElement parentWindowHandle, string sAutomationID)

{

PropertyCondition condition = null;

PropertyCondition codEdit = null;

AndCondition andConditon = null;

AutomationElement targetEditHandle = null;

try

{

if (null == parentWindowHandle)

{

return null;

}

condition = new PropertyCondition(AutomationElement.AutomationIdProperty, sAutomationID);

codEdit = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit);

andConditon = new AndCondition(condition, codEdit);

targetEditHandle = parentWindowHandle.FindFirst(TreeScope.Children, andConditon);

return targetEditHandle;

}

catch (System.Exception ex)

{

string msg = "没有找到指定的TextEdit,请确认TextEdit的AutomationID是否正确!";

throw new InvalidProgramException(msg, ex);

}

}

///<summary>

///根据TextEdit句柄,在TextEdit内填写数据

///只能设置单行输入的TextEdit

///</summary>

public static bool SetTextEditData(AutomationElement TextEditHandle, string strData)

{

ValuePattern vpTextEdit = null;

if (!TextEditHandle.Current.IsEnabled)

{

throw new InvalidOperationException("The control is not enabled.\n\n");

}

if (!TextEditHandle.Current.IsKeyboardFocusable)

{

throw new InvalidOperationException("The control is not focusable.\n\n");

}

vpTextEdit = TextEditHandle.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;

if (null == vpTextEdit)

{

return false;

}

if (vpTextEdit.Current.IsReadOnly)

{

throw new InvalidOperationException("The control is read-only.");

}

vpTextEdit.SetValue(strData);

return true;

}

6. 定义操作ComboBox的相关函数

///<summary>

///根据窗口句柄以及ComboBox控件AutomationID,返回该ComboBox控件句柄

///</summary>

public static AutomationElement GetComboBoxHandle(AutomationElement parentWindowHandle, string sAutomationID)

{

AutomationElement ComboBoxHandle = null;

PropertyCondition NameCondition = null;

PropertyCondition TypeCondition = null;

AndCondition andCondition = null;

if (null == parentWindowHandle || null == sAutomationID)

{

return null;

}

NameCondition = new PropertyCondition(AutomationElement.AutomationIdProperty, sAutomationID);

TypeCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, boBox);

andCondition = new AndCondition(NameCondition, TypeCondition);

ComboBoxHandle = parentWindowHandle.FindFirst(TreeScope.Children, andCondition);

if (null == ComboBoxHandle)

{

return null;

}

return ComboBoxHandle;

}

///<summary>

///根据ComboBox控件句柄,设置数据

///</summary>

public static bool SetComboBoxItemData(AutomationElement ComboBoxHandle, string strData)

{

AutomationElement TextEditHandle = null;

PropertyCondition TypeCondition = null;

ValuePattern vpTextPattern = null;

if (null == ComboBoxHandle || null == strData)

{

return false;

}

TypeCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit);

TextEditHandle = ComboBoxHandle.FindFirst(TreeScope.Children, TypeCondition);

if (null == TextEditHandle)

{

return false;

}

if (!TextEditHandle.Current.IsEnabled)

{

throw new InvalidOperationException("The control is not enabled.\n\n");

}

if (!TextEditHandle.Current.IsKeyboardFocusable)

{

throw new InvalidOperationException("The control is not focusable.\n\n");

}

vpTextPattern = TextEditHandle.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;

if (null == vpTextPattern)

{

return false;

}

if (vpTextPattern.Current.IsReadOnly)

{

throw new InvalidOperationException("The control is read-only.");

}

vpTextPattern.SetValue(strData);

return true;

}

7. 定义操作Button的相关函数

///<summary>

///根据窗口句柄以及Button的AutomationID,返回Button的句柄

///</summary>

public static AutomationElement GetButtonHandle(AutomationElement parentWindowHandle, string sAutomationID)

{

PropertyCondition condition = null;

PropertyCondition codButton = null;

AndCondition andConditon = null;

AutomationElement targetButtonHandle = null;

try

{

if (null == parentWindowHandle)

{

return null;

}

condition = new PropertyCondition(AutomationElement.AutomationIdProperty, sAutomationID);

codButton = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button);

andConditon = new AndCondition(condition, codButton);

targetButtonHandle = parentWindowHandle.FindFirst(TreeScope.Children, andConditon);

return targetButtonHandle;

}

catch (System.Exception ex)

{

string msg = "没有找到指定的按钮,请确认按钮AutomationID是否正确!";

throw new InvalidProgramException(msg, ex);

}

}

///<summart>

///根据Button按钮句柄,进行鼠标左键单击

///</summary>

public static bool ButtonLeftClick(AutomationElement ButtonHandle)

{

object objButton = null;

InvokePattern ivkpButton = null;

try

{

if (null == ButtonHandle)

{

return false;

}

if (!ButtonHandle.TryGetCurrentPattern(InvokePattern.Pattern, out objButton))

{

return false;

}

ivkpButton = (InvokePattern)objButton;

ivkpButton.Invoke();

return true;

}

catch (System.Exception ex)

{

string msg = "鼠标左键单击失败!";

throw new InvalidProgramException(msg, ex);

}

}

8. 定义操作ListBox的相关函数

///<summary>

///根据窗口句柄以及ListBox控件AutomationID,返回该ListBox控件句柄

///</summary>

public static AutomationElement GetListBoxHandle(AutomationElement parentWindowHandle, string sAutomationID)

{

AutomationElement ListBoxHandle = null;

PropertyCondition NameCondition = null;

PropertyCondition TypeCondition = null;

AndCondition andCondition = null;

if (null == parentWindowHandle || null == sAutomationID)

{

return null;

}

NameCondition = new PropertyCondition(AutomationElement.AutomationIdProperty, sAutomationID);

TypeCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.List);

andCondition = new AndCondition(NameCondition, TypeCondition);

ListBoxHandle = parentWindowHandle.FindFirst(TreeScope.Children, andCondition);

if (null == ListBoxHandle)

{

return null;

}

return ListBoxHandle;

}

///<summary>

///根据ListBox控件句柄以及ItemCount,选择该Item

///</summary>

public static string GetListBoxItemName(AutomationElement ListBoxHandle, int iItemCount)

{

AutomationElementCollection ListBoxHandleCollection = null;

PropertyCondition TypeCondition = null;

if (null == ListBoxHandle || 0 > iItemCount)

{

return null;

}

TypeCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ListItem);

ListBoxHandleCollection = ListBoxHandle.FindAll(TreeScope.Children, TypeCondition);

if (null == ListBoxHandleCollection)

{

return null;

}

if (iItemCount >= ListBoxHandleCollection.Count)

{

return null;

}

return ListBoxHandleCollection[iItemCount].Current.Name;

}

9. 定义操作菜单的相关函数

///<summary>

///根据窗口句柄,以及MenuBar控件AutomationID,返回该MenuBar控件句柄

///</summary>

public static AutomationElement GetMenuBarHandle(AutomationElement parentWindow, string sAutomationID)

{

AutomationElement MBHandle = null;

PropertyCondition NameCondition = null;

PropertyCondition TypeCondition = null;

AndCondition andCondition = null;

if (null == parentWindow || null == sAutomationID)

{

return null;

}

NameCondition = new PropertyCondition(AutomationElement.AutomationIdProperty, sAutomationID);

TypeCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.MenuBar);

andCondition = new AndCondition(NameCondition, TypeCondition);

MBHandle = parentWindow.FindFirst(TreeScope.Children, andCondition);

if (null == MBHandle)

{

return null;

}

return MBHandle;

}

///<summary>

///根据MenuBar控件句柄以及一级菜单名称,弹出一级菜单

///</summary>

private static AutomationElement PopupMenuBarItem(AutomationElement MBHandle, string FirMenuTitle)

{

InvokePattern IPMenu = null;

AutomationElement MenuHandle = null;

PropertyCondition NameCondition = null;

PropertyCondition TypeCondition = null;

AndCondition andCondition = null;

if (null == MBHandle || null == FirMenuTitle)

{

return null;

}

NameCondition = new PropertyCondition(AutomationElement.NameProperty, FirMenuTitle);

TypeCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.MenuItem);

andCondition = new AndCondition(NameCondition, TypeCondition);

MenuHandle = MBHandle.FindFirst(TreeScope.Children, andCondition);

if (null == MenuHandle)

{

return null;

}

IPMenu = MenuHandle.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;

if (null == IPMenu)

{

return null;

}

IPMenu.Invoke();

return MenuHandle;

}

///<summary>

///根据MenuBar控件句柄以及传入的菜单名称,选择相应的菜单

///传入的菜单名称,必须以空字符串结束

///</summary>

public static bool SelectMenuBarItem(AutomationElement MBHandle, string[] strTitle)

{

AutomationElement MenuItemHandle = null;

MenuItemHandle = MBHandle;

foreach (string str in strTitle)

{

if ("" == str)

{

break;

}

MenuItemHandle = PopupMenuBarItem(MenuItemHandle, str);

if (null == MenuItemHandle)

{

return false;

}

Thread.Sleep(400);

}

return true;

}

10. 添加测试代码

static void Main(string[] args)

{

string path = Directory.GetCurrentDirectory() + "\\AUT.exe";

try

{

Console.WriteLine("\nStart Application Under Test Exe");

Int32 ProcessId = StartExe(path);

Console.WriteLine("Application Under Test ProcessID: " + ProcessId.ToString());

Console.WriteLine("\nGet Main Window Handle");

AutomationElement mwh = GetWindowHandle(ProcessId, 3000);

Console.WriteLine("Main Window Handle: " + mwh.Current.NativeWindowHandle.ToString());

Console.WriteLine("\nGet TextBox Handle");

AutomationElement tbh = GetTextEditHandle(mwh, "textBox1");

Console.WriteLine("TextBox Handle: " + tbh.Current.NativeWindowHandle.ToString());

Console.WriteLine("\nGet ComboBox Handle");

AutomationElement cbh = GetComboBoxHandle(mwh, "comboBox1");

Console.WriteLine("ComboBox Handle: " + cbh.Current.NativeWindowHandle.ToString());

Console.WriteLine("\nGet Button Handle");

AutomationElement bth = GetButtonHandle(mwh, "button1");

Console.WriteLine("Button Handle: " + bth.Current.NativeWindowHandle.ToString());

Console.WriteLine("\nGet ListBox Handle");

AutomationElement lbh = GetListBoxHandle(mwh, "listBox1");

Console.WriteLine("ListBox Handle: " + lbh.Current.NativeWindowHandle.ToString());

Console.WriteLine("\nSet TextBox Value");

SetTextEditData(tbh, "paper");

Console.WriteLine("\nSet ConboxBox Value");

SetComboBoxItemData(cbh, "rock");

Console.WriteLine("\nPush Mouse Left button");

ButtonLeftClick(bth);

string result = GetListBoxItemName(lbh, 0);

if (result == "The TextBox wins")

{

Console.WriteLine("\nTest seceions = PASS");

}

else

{

Console.WriteLine("\nTest seceions = Failed");

}

Console.WriteLine("\nGet Menu Handle");

AutomationElement mbh = GetMenuBarHandle(mwh, "menuStrip1");

Console.WriteLine("Menu Handle: " + mbh.Current.NativeWindowHandle.ToString());

string[] strTitle = { "File", "Exit", "" };

Console.WriteLine("\nClose Application Under Test in 3 Seconds....");

Thread.Sleep(3000);

SelectMenuBarItem(mbh, strTitle);

Console.ReadLine();

}

catch (System.Exception ex)

{

Console.WriteLine("\nError msg: " + ex.Message);

}

}

11. 编译测试程序,OK,大功告成

————————————————

原文链接:/lassewang/article/details/6693917

如果觉得《.Net软件UI界面测试自动化--UIAutomation技术》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。