.Net软件UI界面测试自动化--Windows API

来源:互联网 发布:淘宝直播视频怎么删除 编辑:程序博客网 时间:2024/06/08 19:54
       在目前进行软件测试时,都或多或少的引入了自动化测试的概念,而且市面上也有好多软件自动化方面相关的工具,比如QTP,比如LoadRunner,但是这些工具要么售价不菲,要么对某些方面功能支持的不够全面,那么我们在引入软件自动化测试时,都需要考虑哪些方面呢?当然是最符合自己项目的工具最合适,同时费用也比较低,那么除了市面上这些商业软件外,还有没有哪些方法可以自己动手来做软件的自动化测试呢?答案是肯定的.

      本文将介绍实现软件自动化测试其中一种测试方法------Windows API技术,当然,此种方法仅限于对.Net软件使用,还有一些比较通用的方法,将在后续的文章中进行介绍(使用UIAutomation类).

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

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

      一. 创建待测试程序

          1. 启动VS2008,建立一个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.Windows.Forms.ComboBox 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. 启动VS2008,创建一个C#控制台程序,并命名为WindowsUITest

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


      using System;      using System.Diagnostics;      using System.Runtime.InteropServices;      using System.Threading;      using System.IO;      using System.Text;
        3. 声明需要使用到的WIndows API

        [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]        static extern IntPtr FindWindow(string lpClassName, string lpWindowsName);        [DllImport("user32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Auto)]        static extern IntPtr FindWindowEx(IntPtr hwndParent,                                           IntPtr hwndChildAfter,                                          string lpszClass,                                          string lpszWindow);        //用于发送WM_CHAR消息        [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]        static extern void SendMessage1(IntPtr hWnd, uint Msg, int wParam, int lParam);        //用于发送WM_COMMAND消息        [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]        static extern void SendMessage2(IntPtr hWnd, uint Msg, int wParam, IntPtr lParam);        //用于发送WM_GETTEXT消息        [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]        static extern int SendMessage3(IntPtr hWndControl, uint Msg, int wParam, byte[] lParam);        //用于发送LB_FINDSTRING消息        [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]        static extern int SendMessage4(IntPtr hWnd, uint Msg, int wParam, byte[] lParam);        //用于发送WM_LBUTTONDOWN和WM_LBUTTONUP消息        [DllImport("user32.dll", EntryPoint="PostMessage", CharSet=CharSet.Auto)]        static extern bool PostMessage1(IntPtr hWnd, uint Msg, int wParam, int lParam);        //菜单函数相关        [DllImport("user32.dll")]        static extern IntPtr GetMenu(IntPtr hWnd);        [DllImport("user32.dll")]        static extern IntPtr GetSubMenu(IntPtr hMenu, int nPos);        [DllImport("user32.dll")]        static extern int GetMenuItemID(IntPtr hMenu, int nPos);
        4. 定义查询窗体的函数

        static IntPtr FindTopLevelWindow(string caption, int delay, int maxTries)        {            IntPtr mwh = IntPtr.Zero;            bool formFount = false;            int attempts = 0;                        do             {                mwh = FindWindow(null, caption);                if (mwh == IntPtr.Zero)                {                    Console.WriteLine("Form not yet found");                    Thread.Sleep(delay);                    ++attempts;                }                else                {                    Console.WriteLine("Form has been found");                    formFount = true;                }            }             while (!formFount && attempts < maxTries);            if (mwh != IntPtr.Zero)            {                return mwh;            }            else            {                throw new Exception("Could not found Main Window");            }                    }        static IntPtr FindMainWindowHandle(string caption, int delay, int maxTries)        {            return FindTopLevelWindow(caption, delay, maxTries);        }        static IntPtr FindMessageBox(string caption)        {            int delay = 100;            int maxTries = 25;            return FindTopLevelWindow(caption, delay, maxTries);        }        static IntPtr FindWindowByIndex(IntPtr hwndParent, int index)        {            if (index == 0)            {                return hwndParent;            }            else            {                int ct = 0;                IntPtr result = IntPtr.Zero;                do                 {                    result = FindWindowEx(hwndParent, result, null, null);                    if (result != IntPtr.Zero)                    {                        ++ct;                    }                }                 while (ct < index && result != IntPtr.Zero);                return result;            }        }
        5.  定义发送字符串/字符的函数

        static void SendChar(IntPtr hControl, char c)        {            uint WM_CHAR = 0x0102;            SendMessage1(hControl, WM_CHAR, c, 0);        }        static void SendChars(IntPtr hControl, string s)        {            foreach (char c in s)            {                SendChar(hControl, c);            }        }
        6. 定义点击鼠标按钮的函数

        static void ClickOn(IntPtr hControl)        {            uint WM_LBUTTONDOWN = 0x0201;            uint WM_LBUTTONUP = 0x0202;            PostMessage1(hControl, WM_LBUTTONDOWN, 0, 0);            PostMessage1(hControl, WM_LBUTTONUP, 0, 0);        }
        7. 编写测试代码

        [STAThread]        static void Main(string[] args)        {            try            {                Console.WriteLine("\nLaunching application under test");                string path = Directory.GetCurrentDirectory() + "\\AUT.exe";                Process p = Process.Start(path);                Thread.Sleep(2000);                Console.WriteLine("\nFinding main window handle");                IntPtr mwh = FindMainWindowHandle("Form1", 100, 25);                Console.WriteLine("Main window handle = " + mwh);                Thread.Sleep(2000);                                //因为测试程序是使用C#创建的,所以控件的Class名称会比较奇怪,可以使用SPY++工具来查看                IntPtr tb = FindWindowEx(mwh, IntPtr.Zero, "WindowsForms10.EDIT.app.0.378734a", "");                IntPtr cb = FindWindowEx(mwh, IntPtr.Zero, "WindowsForms10.COMBOBOX.app.0.378734a", "");                IntPtr bt = FindWindowEx(mwh, IntPtr.Zero, null, "button1");                IntPtr lb = FindWindowEx(mwh, IntPtr.Zero, "WindowsForms10.LISTBOX.app.0.378734a", "");                                if (tb == IntPtr.Zero || cb == IntPtr.Zero ||                    bt == IntPtr.Zero || lb == IntPtr.Zero)                {                    throw new Exception("Unable to find all controls");                }                else                {                    Console.WriteLine("All control handles found");                }                //设置数据                SendChars(tb, "paper");                SendChars(cb, "rock");                ClickOn(bt);                Thread.Sleep(1000);                uint LB_FINDSTRING = 0x018F;                byte[] bResult = Encoding.ASCII.GetBytes("The TextBox wins");                int result = SendMessage4(lb, LB_FINDSTRING, -1, bResult);                //uint WM_GETTEXT = 0x000D;                if (result >= 0)                {                    Console.WriteLine("\nTest scenario result = Pass");                }                else                {                    Console.WriteLine("\nTest scenario result = Fail");                }                Console.WriteLine("\nExiting app in 3 seconds...");                Thread.Sleep(3000);                IntPtr hMainMenu = GetMenu(mwh);                //IntPtr hMainMenu = FindWindowEx(mwh, IntPtr.Zero, "WindowsForms10.Window.8.app.0.378734a", null);                IntPtr hFile = GetSubMenu(hMainMenu, 0);                int iexit = GetMenuItemID(hFile, 0);                uint WM_COMMAND = 0x0111;                SendMessage2(mwh, WM_COMMAND, iexit, IntPtr.Zero);                Console.WriteLine("\nDone");                Console.ReadLine();            }            catch (System.Exception ex)            {                        }        }
        8.  编译测试程序,OK,大功告成


原创粉丝点击