zoukankan      html  css  js  c++  java
  • 使用UI Automation实现自动化测试6 (模拟鼠标在自动化测试中的应用)

    模拟鼠标在自动化测试中的应用

         尽管UI Automation可以实现控件的自动化,但是,自定义控件的自动化往往由于自定义控件中对自动化的支持不够,而导致无法使用UI Automation的相关Pattern来操作此控件。此时我们可以使用模拟鼠标的操作来达到相应的效果。

    . NET并没有提供改变鼠标指针位置、模拟点击操作的函数;但是Windows API提供了。在.NET中模拟鼠标通常是调用底层的API来实现。

    注:在使用前必须添加using System.Runtime.InteropServices;命名空间。

    移动鼠标到指定的位置

    /// <summary>

    /// Add mouse move event

    /// </summary>

    /// <param name="x">Move to specify x coordinate</param>

    /// <param name="y">Move to specify y coordinate</param>

    /// <returns></returns>

     [DllImport("user32.dll")]

    extern static bool SetCursorPos(int x, int y);

    该函数可以改变鼠标指针的位置。其中xy是相对于屏幕左上角的绝对位置。

    移动鼠标到指定的位置并进行相应的鼠标操作

    /// <summary>

    /// Mouse click event

    /// </summary>

    /// <param name="mouseEventFlag">MouseEventFlag </param>

    /// <param name="incrementX">X coordinate</param>

    /// <param name="incrementY">Y coordinate</param>

    /// <param name="data"></param>

    /// <param name="extraInfo"></param>

    [DllImport("user32.dll")]

    extern static void mouse_event(int mouseEventFlag, int incrementX, int incrementY, uint data, UIntPtr extraInfo);

    这个函数不仅可以设置鼠标指针绝对的位置,而且可以以相对坐标来设置。另外,该函数还可以模拟鼠标左右键点击、鼠标滚轮操作等。其中的MouseEventFlag是一个常量,定义如下:

    const int MOUSEEVENTF_MOVE = 0x0001;

    const int MOUSEEVENTF_LEFTDOWN = 0x0002;

    const int MOUSEEVENTF_LEFTUP = 0x0004;

    const int MOUSEEVENTF_RIGHTDOWN = 0x0008;

    const int MOUSEEVENTF_RIGHTUP = 0x0010;

    const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;

    const int MOUSEEVENTF_MIDDLEUP = 0x0040;

    const int MOUSEEVENTF_ABSOLUTE = 0x8000;

    上面列举的两个函数的详细说明,可参考MSDN帮助文档。

    如下代码为在控件的指定位置上单击鼠标左键和右键。

    public void ClickLeftMouse(int processId, string automationId)

    {

        AutomationElement element = FindElementById(processId, automationId);

        if (element == null)

        {

            throw new NullReferenceException(string.Format("Element with AutomationId '{0}' and Name '{1}' can not be find.",

                element.Current.AutomationId, element.Current.Name));

        }

     

        Rect rect = element.Current.BoundingRectangle;

        int IncrementX = (int)(rect.Left + rect.Width / 2);

        int IncrementY = (int)(rect.Top + rect.Height / 2);

     

        //Make the cursor position to the element.

        SetCursorPos(IncrementX, IncrementY);

        //Make the left mouse down and up.

        mouse_event(MOUSEEVENTF_LEFTDOWN, IncrementX, IncrementY, 0, 0);

        mouse_event(MOUSEEVENTF_LEFTUP, IncrementX, IncrementY, 0, 0);

    }

     

    public void ClickRightMouse(int processId, string automationId)

    {

        AutomationElement element = FindElementById(processId, automationId);

        if (element == null)

        {

            throw new NullReferenceException(string.Format("Element with AutomationId '{0}' and Name '{1}' can not be find.",

                element.Current.AutomationId, element.Current.Name));

        }

     

        Rect rect = element.Current.BoundingRectangle;

        int IncrementX = (int)(rect.Left + rect.Width / 2);

        int IncrementY = (int)(rect.Top + rect.Height / 2);

     

        //Make the cursor position to the element.

        SetCursorPos(IncrementX, IncrementY);

        //Make the left mouse down and up.

        mouse_event(MOUSEEVENTF_RIGHTDOWN, IncrementX, IncrementY, 0, 0);

        mouse_event(MOUSEEVENTF_RIGHTUP, IncrementX, IncrementY, 0, 0);

    }

    在上面的代码中,我们通过如下步骤来达到点击鼠标的目的:

    1.       通过UI Automation来找到需要鼠标点击的控件;

    2.       然后取得此控件的坐标;

    3.       在设置点击坐标在控件的中心位置;

    4.       移动鼠标的位置到控件的中心位置(此步骤可以不要,但是为了达到双保险的效果,我们还是移动一次)。

    5.       调用Win32 API模拟鼠标点击控件。

    注:Rect需要引用WindowBase.dll,添加using System.Windows;明明空间。

        下面的例子演示了通过模拟鼠标左键点击button来弹出对话框,并且模拟鼠标点击对话框中的“OK”按钮关闭对话框。

    using System;

    using System.Text;

    using System.Diagnostics;

    using System.Threading;

    using System.Windows.Automation;

    using System.Runtime.InteropServices;

    using System.Windows;

     

    namespace UIATest

    {

        class Program

        {

            static void Main(string[] args)

            {

                Process process = Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\ATP.TestForm\bin\Debug\ATP.TestForm.exe");

                int processId = process.Id;

                Thread.Sleep(1000);

     

                ClickLeftMouse(processId, "button1");

                Thread.Sleep(3000);

     

                ClickLeftMouse(processId, "2");

                Console.WriteLine("Test finised.");

            }

     

            #region ClickMouse

     

            #region Import DLL

            /// <summary>

            /// Add mouse move event

            /// </summary>

            /// <param name="x">Move to specify x coordinate</param>

            /// <param name="y">Move to specify y coordinate</param>

            /// <returns></returns>

            [DllImport("user32.dll")]

            extern static bool SetCursorPos(int x, int y);

     

            /// <summary>

            /// Mouse click event

            /// </summary>

            /// <param name="mouseEventFlag">MouseEventFlag </param>

            /// <param name="incrementX">X coordinate</param>

            /// <param name="incrementY">Y coordinate</param>

            /// <param name="data"></param>

            /// <param name="extraInfo"></param>

            [DllImport("user32.dll")]

            extern static void mouse_event(int mouseEventFlag, int incrementX, int incrementY, uint data, UIntPtr extraInfo);

     

            const int MOUSEEVENTF_MOVE = 0x0001;

            const int MOUSEEVENTF_LEFTDOWN = 0x0002;

            const int MOUSEEVENTF_LEFTUP = 0x0004;

            const int MOUSEEVENTF_RIGHTDOWN = 0x0008;

            const int MOUSEEVENTF_RIGHTUP = 0x0010;

            const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;

            const int MOUSEEVENTF_MIDDLEUP = 0x0040;

            const int MOUSEEVENTF_ABSOLUTE = 0x8000;

     

            #endregion 

            public static void ClickLeftMouse(int processId, string automationId)

            {

                AutomationElement element = FindElementById(processId, automationId);

     

                if (element == null)

                {

                    throw new NullReferenceException(string.Format("Element with AutomationId '{0}' and Name '{1}' can not be find.",

                        element.Current.AutomationId, element.Current.Name));

                }

     

                Rect rect = element.Current.BoundingRectangle;

                int IncrementX = (int)(rect.Left + rect.Width / 2);

                int IncrementY = (int)(rect.Top + rect.Height / 2);

     

                //Make the cursor position to the element.

                SetCursorPos(IncrementX, IncrementY);

     

                //Make the left mouse down and up.

                mouse_event(MOUSEEVENTF_LEFTDOWN, IncrementX, IncrementY, 0, UIntPtr.Zero);

                mouse_event(MOUSEEVENTF_LEFTUP, IncrementX, IncrementY, 0, UIntPtr.Zero);

            }

     

            #endregion

     

            /// <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;

            }

        }

    }

    Summary

         本节首先简单介绍了如何在.NET中模拟鼠标操作,进而通过实例演示了模拟鼠标在基于UI Automation的自动化测试中应用。

  • 相关阅读:
    Exchange ProxyLogon漏洞分析
    Java安全之Dubbo反序列化漏洞分析
    c# 基础语法
    Java安全之Axis漏洞分析
    c# 反射调用
    Exchange CVE20200688代码执行漏洞分析
    Windows上使用pm2运行Net Core项目
    重新点亮shell————测试命令[六]
    重新点亮shell————sed其他命令[十一]
    重新点亮shell————awk 控制语句[十三]
  • 原文地址:https://www.cnblogs.com/kangyi/p/1592242.html
Copyright © 2011-2022 走看看