.NET自动化测试手记(2) 实例:点击计算器按钮

这篇文章主要介绍通过.NET结合Win32 API来实现点击计算器上一个按钮的操作。

假设已经有一个“计算器”程序在运行,操作步骤如下:

  1. 添加程序集引用: WindowsBase, UIAutomationClient 和 UIAutomationTypes

  

  2. 引用命名空间:  

引用命名空间
using System.Windows;
using System.Runtime.InteropServices; //调用Win32 API
using System.Windows.Automation; //使用.NET Automation类

  3. 声明对Win32 API的引用

添加Win32引用
        [DllImport("User32.dll")]
public static extern bool SetForegroundWindow(int handler);                 //将对应句柄的窗口在屏幕最前端显示并激活


[DllImport("user32.dll")]
public static extern void mouse_event(MouseEventFlag flags, int dx, int dy, uint data, UIntPtr extraInfo);  //这里将实现鼠标的模拟操作

[Flags]
public enum MouseEventFlag : uint
{
Move = 0x0001,
LeftDown = 0x0002,
LeftUp = 0x0004,
RightDown = 0x0008,
RightUp = 0x0010,
MiddleDown = 0x0020,
MiddleUp = 0x040,
XDown = 0x0080,
XUp = 0x0100,
Wheel = 0x0800,
VirtualDesk = 0x4000,
Absolute = 0x8000
}

  4. 查找Title为“Calculator”的窗体

查找Calculator的主窗体
    AutomationElement desk = AutomationElement.RootElement;
    AutomationElement eleWindow = GetWindowByName(desk, "Calculator");
根据窗体名字获取窗体元素的方法定义
     public static AutomationElement GetWindowByName(AutomationElement parent, string name)  
{
if (parent == null)
{
throw new Exception("Parent element is null!");
}

PropertyCondition nameProperty = new PropertyCondition(AutomationElement.NameProperty, name);
PropertyCondition typeProperty = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window);
AndCondition andCondition = new AndCondition(nameProperty, typeProperty);

return parent.FindFirst(TreeScope.Descendants | TreeScope.Element, andCondition);
}

  5. 获取窗体中对应的Button(例如“3”)

AutomationElement eleButton = FindControlInWindow(eleWindow, "3");
根据名字获取窗体中对应Button的方法
        public static AutomationElement FindControlInWindow(AutomationElement window, string name)
{
if (window==null)
{
throw new Exception("Target window is null!");
}

PropertyCondition nameProperty = new PropertyCondition(AutomationElement.NameProperty, name);
PropertyCondition typeProperty = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button);
AndCondition andCondition = new AndCondition(nameProperty, typeProperty);

return window.FindFirst(TreeScope.Descendants | TreeScope.Element, andCondition);
}

  6. 点击Button

点击Button
            InvokePattern buttonClick = (InvokePattern)eleButton.GetCurrentPattern(InvokePattern.Pattern);
buttonClick.Invoke();

到这里,一个简单的点击计算器的操作就完成了,结果如下图:

当然,还可以通过Win32 API来实现一些可视化的操作,比如

  1. 在获得窗体之后可以将窗体激活并显示在屏幕最前面

添加Win32引用
        [DllImport("User32.dll")]
public static extern bool SetForegroundWindow(int handler); //将对应句柄的窗口在屏幕最前端显示并激活
调用SetForegroundWindow
    SetForegroundWindow(eleWindow.Current.NativeWindowHandle);

  2. 实现鼠标的移动和点击

添加Win32引用
        [DllImport("user32.dll")]
public static extern void mouse_event(MouseEventFlag flags, int dx, int dy, uint data, UIntPtr extraInfo); //这里将实现鼠标的模拟操作

[Flags]
public enum MouseEventFlag : uint
{
Move = 0x0001,
LeftDown = 0x0002,
LeftUp = 0x0004,
RightDown = 0x0008,
RightUp = 0x0010,
MiddleDown = 0x0020,
MiddleUp = 0x040,
XDown = 0x0080,
XUp = 0x0100,
Wheel = 0x0800,
VirtualDesk = 0x4000,
Absolute = 0x8000
}
移动鼠标到Button上并点击
    Cursor.Position = new System.Drawing.Point((int)eleButton.Current.BoundingRectangle.Left+(int)eleButton.Current.BoundingRectangle.Size.Width/2, (int)eleButton.Current.BoundingRectangle.Top+(int)eleButton.Current.BoundingRectangle.Size.Height/2);
    mouse_event(MouseEventFlag.LeftDown | MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);

 

好了,到这里要介绍的内容就已经说完了。但是还有一些操作始终解决不了:

1. 使用Win32获得“计算器”里面数字按钮的句柄

2. 使用.NET类来模拟鼠标的操作(不调用Win32)

如果有哪位朋友有这两个问题的解决方案,希望能够指点一下...





原文地址:https://www.cnblogs.com/silverbullet11/p/2349933.html