使用UI Automation实现自动化测试--7.1 (模拟键盘输入数据在自动化测试中的应用)

Chapter 7 Simulated keyboard

 

7.1 模拟键盘输入

7.1.1 Introduction

此部分我们通过System.Windows.Forms.SendKeys类中的Send方法来模拟通过键盘输入数据到相应的控件中。

7.1.2 SendKeys Class IntroductionMSDN

使用 SendKeys 将键击和组合键击发送到活动应用程序。此类无法实例化。若要发送一个键击给某个类并立即继续程序流,请使用 Send。若要等待键击启动的任何进程,请使用 SendWait

每个键都由一个或多个字符表示。若要指定单个键盘字符,请使用该字符本身。例如,若要表示字母 A,请将字符串“A”传递给方法。若要表示多个字符,请将各个附加字符追加到它之前的字符的后面。若要表示字母 AB C,请将参数指定为“ABC”

加号 (+)、插入符号 (^)、百分号 (%)、波浪号 (~) 以及圆括号 ( ) SendKeys 具有特殊含义。若要指定这些字符中的某个字符,请将其放在大括号 ({}) 内。例如,若要指定加号,请使用“{+}”。若要指定大括号字符,请使用“{{}”“{}}”。中括号 ([ ]) SendKeys 没有特殊含义,但必须将它们放在大括号内。在其他应用程序中,中括号具有特殊含义,此含义可能会在发生动态数据交换 (DDE) 时起重要作用。

7.1.3 SendKeys MethodMSDN

SendKeys有两个重要的方法:

1.         Send方法:向活动应用程序发送击键。 

2.         SendWait方法:向活动应用程序发送给定的键,然后等待消息被处理。 

有关SendKeys的参考:

英文站点:http://msdn.microsoft.com/en-us/library/8c6yea83(VS.85).aspx

中文站点:http://msdn.microsoft.com/zh-cn/library/system.windows.forms.sendkeys_methods(VS.80).aspx

 

    下面我们通过一个实例来演示通过SendKeys类来模拟键盘操作进行数据输入和快捷菜单的打开:

using System;

using System.Text;

using System.Diagnostics;

using System.Threading;

using System.Windows.Automation;

using System.Runtime.InteropServices;

using System.Windows;

using System.Windows.Forms;

 

namespace UIATest

{

    class Program

    {

        static void Main(string[] args)

        {

            Process process = Process.Start(@"E:\WorkBook\ATP\WpfApp\bin\Debug\WpfApp.exe");

            int processId = process.Id;

 

            AutomationElement element = FindElementById(processId, "textBox1");

            SendKeys sendkeys = new SendKeys();

            sendkeys.Sendkeys(element, "Sending keys to input data");

            Console.WriteLine(sendkeys.ToString());

            sendkeys.Sendkeys(element, sendkeys.ContextMenu);

            Console.WriteLine(sendkeys.ToString());

            Console.WriteLine("Test finised.");  

        }

 

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

        }

    }

}

      我们自定义一个SendKeys类来对已有的SendKeys类进行优化,代码如下:

using System;

using System.Windows.Automation;

using System.Threading;

using System.Text;

using System.Windows.Forms;

 

namespace UIATest

{

    public class SendKeys

    {

        StringBuilder builder = new StringBuilder();

 

        public string Alt = "%";

        public string ContextMenu = "+{F10}";

        public string Ctrl = "^";

        public string Shift = "+";

        public string Enter = "{Enter}";

        public string Delete = "{Del}";

        public string Save = "^S";

        public string SaveAll = "^+S";

        public string Copy = "^C";

        public string Cut = "^X";

        public string Paste = "^V";

        public string Undo = "^Z";

        public string Redo = "^Y";

        public string Print = "^P";

        public string Help = "{F1}";

        public string New = "^N";

 

        public string[] Keys{ get; set; }

 

 

        public void Sendkeys(AutomationElement element, string[] keys)

        {

            this.Keys = keys;

            try

            {

                element.SetFocus();

            }

            catch (Exception exception)

            {

                throw new Exception("Cannot set focus to this element.", exception);

            }

            string myKeys = "";

            foreach (string str2 in this.Keys)

            {

                myKeys = myKeys + str2;

            }

            Thread.Sleep(200);

            if ((this.ContainsUnescapedKey(myKeys, '^') || this.ContainsUnescapedKey(myKeys, '%')) || this.ContainsUnescapedKey(myKeys, '+'))

            {

                myKeys = myKeys.ToLower();

            }

            System.Windows.Forms.SendKeys.SendWait(myKeys);

            Thread.Sleep(0x3e8);

        }

 

        public void Sendkeys(AutomationElement element, string myKeys)

        {

            this.Keys = new string[1];

            this.Keys[0] = myKeys;

            try

            {

                element.SetFocus();

            }

            catch (Exception exception)

            {

                throw new Exception("Cannot set focus to this element.", exception);

            }

            Thread.Sleep(200);

            if ((this.ContainsUnescapedKey(myKeys, '^') || this.ContainsUnescapedKey(myKeys, '%')) || this.ContainsUnescapedKey(myKeys, '+'))

            {

                myKeys = myKeys.ToLower();

            }

            System.Windows.Forms.SendKeys.SendWait(myKeys);

            Thread.Sleep(0x3e8);

        }

       

        private bool ContainsUnescapedKey(string keys, char key)

        {

            for (int i = 0; i < keys.Length; i++)

            {

                if (keys[i] == key)

                {

                    if ((i == 0) || (i == (keys.Length - 1)))

                    {

                        return true;

                    }

                    if ((keys[i - 1] != '{') || (keys[i + 1] != '}'))

                    {

                        return true;

                    }

                }

            }

            return false;

        }

 

        private string KeysToString(string[] keys)

        {

           

            if (keys != null)

            {

                for (int i = 0; i < keys.Length; i++)

                {

                    string str = keys[i];

                    if (str == null)

                    {

                        builder.Append(keys[i]);

                    }

                    int length = keys.Length - 1;

                    switch (str)

                    {

                        case "^":

                            builder.Append("Ctrl");

                            IsEquals(i, length, builder);

                            break;

                        case "+{F10}":

                            builder.Append("Open Context Menu");

                            IsEquals(i, length, builder);

                            break;

                        case "%":

                            builder.Append("Alt");

                            IsEquals(i, length, builder);

                            break;

                        case "+":

                            builder.Append("Shift");

                            IsEquals(i, length, builder);

                            break;

                        case "^S":

                            builder.Append("Save");

                            IsEquals(i, length, builder);

                            break;

                        case "^X":

                            builder.Append("Cut");

                            IsEquals(i, length, builder);

                            break;

                        case "^C":

                            builder.Append("Copy");

                            IsEquals(i, length, builder);

                            break;

                        case "^V":

                            builder.Append("Paste");

                            IsEquals(i, length, builder);

                            break;

                        case "^+S":

                            builder.Append("Save All");

                            IsEquals(i, length, builder);

                            break;

                        case "^P":

                            builder.Append("Print");

                            IsEquals(i, length, builder);

                            break;

                        case "^Z":

                            builder.Append("Undo");

                            IsEquals(i, length, builder);

                            break;

                        case "^Y":

                            builder.Append("Redo");

                            IsEquals(i, length, builder);

                            break;

                        case "^N":

                            builder.Append("New");

                            IsEquals(i, length, builder);

                            break;

                        default:

                            builder.Append(keys[i]);

                            IsEquals(i, length, builder);

                            break;

                    }

                }

            }

            return builder.ToString();

        }

 

        void IsEquals(int i, int length, StringBuilder builder)

        {

            if(i<length)

                builder.Append("+");

        }

           

        #region Public Method

 

        public override string ToString()

        {

            return string.Format("Sendkeys to input data or operator with keys = '{0}'",

                this.KeysToString(Keys));

        }

        #endregion

    }

}

    如下代码为对应的WPF窗体XAML代码:

<Window x:Class="WpfApp.SendKeysInputData"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="SendKeysInputData" Height="250" Width="367">

    <Grid>

        <TextBox Margin="28,80,41,101" Name="textBox1">

            <TextBox.ContextMenu>

                <ContextMenu>

                    <MenuItem Header="Open" />

                    <MenuItem Header="Save" />

                    <MenuItem Header="New" />

                    <MenuItem Header="Save As" />

                    <MenuItem Header="Load" />

                    <MenuItem Header="ReLoad" />

                </ContextMenu>

            </TextBox.ContextMenu>

        </TextBox>

    </Grid>

</Window>

7.1.4 Summary

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

你可能感兴趣的:(automation)