• 自动化测试


    https://www.microsoft.com/en-us/download/confirmation.aspx?id=8279 下载windowsSDK

    https://www.cnblogs.com/silverbullet11/category/354374.html

    https://www.cnblogs.com/Luouy/p/4204319.html

     https://www.cnblogs.com/ellie-test/p/4427323.html

    如鹏网 杨中科

    https://www.cnblogs.com/rupeng/p/4876368.html

    http://www.voidcn.com/article/p-uztuqsgm-xy.html

    https://blog.csdn.net/lassewang/article/details/6693917

    使用Win32API模拟点击

    API 说明和例子

            [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
            public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    lpClassName 就是win32 RegisterClass的名字。

    lpWindowName 是窗口的title,如果第一个参数为null,会搜索所有和lpWindowName匹配的窗口。

            [DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true)]
            public static extern IntPtr FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow);

    找到第一个和指定条件符合(class 和windowName 相符合)的hwndParent的子窗口。

    如果hwndParent为null,那么以桌面窗口为父窗口。

    hwndChildAfer必须为Parent的子窗口,函数从该子窗口的下一个子窗口开始搜索。如果为null,函数会从parent的第一个子窗口搜索。

            [DllImport("user32.dll")]
            public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);
     
            public delegate bool CallBack(IntPtr hwnd, int lParam);

    枚举一个父窗口所有的子窗口。

    如果回调函数返回true,继续。返回false,终止枚举。

     被测试的窗口如下图

     点击之后弹出一个messagebox。You Nailed it。

    控制程序的代码

            private void button1_Click(object sender, EventArgs e)
            {
                IntPtr mainHandle = WindowsApi.FindWindow(null, "测试窗口");
                if(mainHandle!=IntPtr.Zero)
                {
                    //MessageBox.Show("find one");
                    IntPtr ibtn = WindowsApi.FindWindowExtended(mainHandle, "ClickMe", true);
                    if(ibtn!=IntPtr.Zero)
                    {
                        WindowsApi.SendMessage(ibtn, 0xF5, 0, 0);
                    }
                }
            }
    static class WindowsApi
        {
            
            [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
            public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
     
            [DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true)]
            public static extern IntPtr FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow);
     
            [DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
            public static extern int SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam);
     
            [DllImport("user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true)]
            public static extern void SetForegroundWindow(IntPtr hwnd);
     
            [DllImport("user32.dll")]
            public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);
     
            public delegate bool CallBack(IntPtr hwnd, int lParam);
            /// <summary>
            /// 查找窗体上控件句柄
            /// </summary>
            /// <param name="hwnd">父窗体句柄</param>
            /// <param name="lpszWindow">控件标题</param>
            /// <param name="bChild">设定是否在子窗体中查找</param>
            /// <returns>控件句柄,没找到返回IntPtr.Zero</returns>
            public static IntPtr FindWindowExtended(IntPtr hwnd,string lpszWindow,bool bChild)
            {
    
                IntPtr iResult = IntPtr.Zero;
                // 首先在父窗体上查找控件
                iResult = WindowsApi.FindWindowEx(hwnd, 0, null, lpszWindow);
                // 如果找到直接返回控件句柄
                if (iResult != IntPtr.Zero) return iResult;
    
                // 如果设定了不在子窗体中查找
                if (!bChild) return iResult;
    
                // 枚举子窗体,查找控件句柄
                int i = WindowsApi.EnumChildWindows(
                hwnd,
                (h, l) =>
                {
                    IntPtr f1 = WindowsApi.FindWindowEx(h, 0, null, lpszWindow);
                    if (f1 == IntPtr.Zero)
                        return true;
                    else
                    {
                        iResult = f1;
                        return false;
                    }
                },
                0);
                // 返回查找结果
                return iResult;
            }
    
        }
    WindowsApi代码

    点击button1,被测试的程序的ClickMe按钮被点击,弹出

    UI Automation简介

    AutomationElement.RootElement 是窗口根元素,桌面。

    AutomationElement.FromHandle(IntPtr hwnd)从窗口句柄拿到AutomationElement对象。

    AutomationElement.Current.***得到控件的名字,句柄等信息。

    例子1:获取所有窗口,打印其名称和classname

    获取桌面,通过FindAll 获取其所有Children

            private void button2_Click(object sender, EventArgs e)
            {
                AutomationElement desktop = AutomationElement.RootElement;
                //MessageBox.Show(desktop.Current.ControlType.ProgrammaticName);
                AutomationElementCollection topWindows=desktop.FindAll(TreeScope.Children, Condition.TrueCondition);
                StringBuilder sb = new StringBuilder();
                foreach(AutomationElement ae in topWindows)
                {
                    sb.AppendLine("Name: " + ae.Current.Name + " ;ClassName=" + ae.Current.ClassName);
    
                }
                MessageBox.Show(sb.ToString());
            }

    效果如下

    添加查询条件

    AutomationElementCollection topWindows=desktop.FindAll(TreeScope.Children, 
                    new PropertyCondition(AutomationElement.ClassNameProperty,"Chrome_WidgetWin_1"));

     例子2:打印计算器程序的所有按钮信息

            private void button2_Click(object sender, EventArgs e)
            {
                AutomationElement desktop = AutomationElement.RootElement;
                AutomationElement calcApp = desktop.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "ApplicationFrameWindow"));
                //looking for all buttons
                var buttons=calcApp.FindAll(TreeScope.Descendants, new PropertyCondition(AutomationElement.ClassNameProperty, "Button"));
                StringBuilder sb = new StringBuilder();
                foreach(AutomationElement ae in buttons)
                {
                    sb.AppendLine(ae.Current.Name);
                }
                MessageBox.Show(sb.ToString());
            }

     

    教程:如何设置文本,读取文本,点击按钮

    设置控件的值

    var p1=(ValuePattern)ele.GetCurrentPattern(ValuePattern.Pattern);
    
    p1.SetValue(value);

    得到文本控件的值

    var p2=(TextPattern)e.GetCurrentPattern(TextPattern.Pattern);
    return p2.DocumentRange.GetText(-1);

    调用控件,比如点击按钮

    var p3=(InvokePattern)e.GetCurrentPattern(InvokePattern.Pattern);
    p3.Invoke();

    例子3:模拟点击按钮,并且返回最终显示值。

            private void button2_Click(object sender, EventArgs e)
            {
                AutomationElement desktop = AutomationElement.RootElement;
                AutomationElement calcApp = desktop.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "ApplicationFrameWindow"));
                //looking for all buttons
                var buttons=calcApp.FindAll(TreeScope.Descendants, new PropertyCondition(AutomationElement.ClassNameProperty, "Button"));
                var button5 = calcApp.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "num5Button"));
                var display = calcApp.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "CalculatorResults"));
    
                var p=(InvokePattern)button5.GetCurrentPattern(InvokePattern.Pattern);
                p.Invoke();
                MessageBox.Show(display.Current.Name);
            }

     例子4:设置文本,点击按钮,获取结果文本框中的值

            private void button2_Click(object sender, EventArgs e)
            {
                AutomationElement desktop = AutomationElement.RootElement;AutomationElement convApp = desktop.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "WinXP multibyte app"));
                var tbInt = convApp.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "1001"));
                var btnConv = convApp.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "IntToBit"));
                var tbShow = convApp.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "1006"));
    
                var p1 = (ValuePattern)tbInt.GetCurrentPattern(ValuePattern.Pattern);
    
                p1.SetValue("25");
    
                var p3 = (InvokePattern)btnConv.GetCurrentPattern(InvokePattern.Pattern);
                p3.Invoke();
    
                var p2 = (TextPattern)tbShow.GetCurrentPattern(TextPattern.Pattern);
                string hello=p2.DocumentRange.GetText(-1);
                MessageBox.Show(hello);
    
            }
  • 相关阅读:
    #pragma 预处理指令
    C++类继承中的构造函数和析构函数 调用顺序
    static_cast与dynamic_cast转换 最简单的理解
    std::map的insert和下标[]访问
    C++有没有string转化int的函数,怎样转换
    c++中在一个类中定义另一个只有带参数构造函数的类的对象
    c++二进制文件的读写
    C++ 包含头文件 和 宏的使用 和 条件编译
    C++ 前置声明 和 包含头文件 如何选择
    C语言 gets()和scanf()函数的区别
  • 原文地址:https://www.cnblogs.com/noigel/p/11444796.html
Copyright © 2020-2023  润新知