.Net软件UI界面测试自动化--反射技术

      在目前进行软件测试时,都或多或少的引入了自动化测试的概念,而且市面上也有好多软件自动化方面相关的工具,比如QTP,比如LoadRunner,但是这些工具要么售价不菲,要么对某些方面功能支持的不够全面,那么我们在引入软件自动化测试时,都需要考虑哪些方面呢?当然是最符合自己项目的工具最合适,同时费用也比较低,那么除了市面上这些商业软件外,还有没有哪些方法可以自己动手来做软件的自动化测试呢?答案是肯定的.

      本文将介绍实现软件自动化测试其中一种测试方法------反射技术,当然,此种方法仅限于对.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#控制台程序,并命名为ReflectionUITest

           2. 在工程中添加两个引用:System.Windows.Form以及System.Drawing

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

       using System;
       using System.Reflection;
       using System.Windows.Forms;
       using System.Threading;
       using System.Drawing;
       using System.IO;

           4. 编写启动待测试程序的函数

        static Form LaunchApp(string path, string formName)
        {
            Form result = null;
            //通过反射技术时,可以通过Assembly类来进行,此处将待测试程序动态加载生成Assembly类
            Assembly a = Assembly.LoadFrom(path);
            //获取Assembly类的类型
            Type t = a.GetType(formName);            
            //创建Form的实例
            result = (Form)a.CreateInstance(t.FullName);            
            //设置线程启动时运行的函数
            AppState aps = new AppState(result);
            ThreadStart ts = new ThreadStart(aps.RunApp);
            //启动线程
            Thread thread = new Thread(ts);
            thread.Start();
            //返回Form实例
            return result;
        }

        private class AppState
        {
            public readonly Form formToRun;

            public AppState(Form f)
            {
                this.formToRun = f;
            }

            public void RunApp()
            {
                Application.Run(formToRun);
            }
        }
           5. 设置窗体的属性信息

        //定义一个委托事件
        delegate void SetFormPropertyValueHandler(Form f, string propertyName, object newValue);
        static void SetFormPropertyValue(Form f, string propertyName, object newValue)
        {
            if (f.InvokeRequired)
            {
                Delegate d = new SetFormPropertyValueHandler(SetFormPropertyValue);
                object[] o = new object[] { f, propertyName, newValue };
                f.Invoke(d, o);
                are.WaitOne();
            }
            else
            {
                //获取窗体的类型
                Type t = f.GetType();
                //根据指定的属性来获取PropertyInfo信息
                PropertyInfo pi = t.GetProperty(propertyName);
                //设置属性值
                pi.SetValue(f, newValue, null);
                are.Set();
            }
        }
           6. 获取窗体的属性

        delegate object GetFormPropertyValueHandler(Form f, string propertyName);
        static object GetFormPropertyValue(Form f, string propertyName)
        {
            if (f.InvokeRequired)
            {
                Delegate d = new GetFormPropertyValueHandler(GetFormPropertyValue);
                object[] o = new object[] { f, propertyName };
                object iResult = f.Invoke(d, o);
                are.WaitOne();
                return iResult;
            }
            else
            {
                Type t = f.GetType();
                PropertyInfo pi = t.GetProperty(propertyName);
                object gResult = pi.GetValue(f, null);
                are.Set();
                return gResult;
            }
        }
           7. 设置窗体中指定控件的信息

        delegate void SetControlPropertyValueHandler(Form f, string controlName, string propertyName, object newValue);
        static void SetControlPropertyValue(Form f, string controlName, string propertyName, object newValue)
        {
            if (f.InvokeRequired)
            {
                Delegate d = new SetControlPropertyValueHandler(SetControlPropertyValue);
                object[] o = new object[] { f, controlName, propertyName, newValue };
                f.Invoke(d, o);
                are.WaitOne();
            }
            else
            {
                //获取窗体的类型
                Type t1 = f.GetType();
                //根据控件名称获取指定的FieldInfo信息
                FieldInfo fi = t1.GetField(controlName, flags); 
                //获取指定控件的对象               
                object ctrl = fi.GetValue(f);     
                //获取指定控件对象的类型           
                Type t2 = ctrl.GetType();
                //查找指定的属性
                PropertyInfo pi = t2.GetProperty(propertyName);
                //设置属性值
                pi.SetValue(ctrl, newValue, null);                
                are.Set();
            }
        }
           8. 获取窗体中指定控件的信息

        delegate object GetControlPropertyValueHandler(Form f, string controlName, string propertyName);
        static object GetControlPropertyValue(Form f, string controlName, string propertyName)
        {
            if (f.InvokeRequired)
            {
                Delegate d = new GetControlPropertyValueHandler(GetControlPropertyValue);
                object[] o = new object[] { f, controlName, propertyName };
                object iResult = f.Invoke(d, o);
                are.WaitOne();
                return iResult;
            }
            else
            {
                Type t1 = f.GetType();
                FieldInfo fi = t1.GetField(controlName, flags);
                object ctrl = fi.GetValue(f);
                Type t2 = ctrl.GetType();
                PropertyInfo pi = t2.GetProperty(propertyName);
                object gResult = pi.GetValue(ctrl, null);
                are.Set();
                return gResult;
            }
        }
           9. 执行指定的函数

        delegate void InvokeMethodHandler(Form f, string methodName, params object[] parms);
        static void InvokeMethod(Form f, string methodName, params object[] parms)
        {
            if (f.InvokeRequired)
            {
                Delegate d = new InvokeMethodHandler(InvokeMethod);
                f.Invoke(d, new object[] { f, methodName, parms });
                are.WaitOne();
            }
            else
            {
                Type t = f.GetType();
                MethodInfo mi = t.GetMethod(methodName, flags);
                mi.Invoke(f, parms);
                are.Set();
            }
        }
           10. 声明需要使用到的变量

        static BindingFlags flags = BindingFlags.Public |
                                                   BindingFlags.NonPublic |
                                                   BindingFlags.Static |
                                                   BindingFlags.Instance;
        static AutoResetEvent are = new AutoResetEvent(false);
           11. 编写测试代码

            try
            {
                Console.WriteLine("\nStart test scenario");
                Console.WriteLine("\nLaunching Form1");

                Form theform = null;
                string formName = "AUT.Form1";
                string path = Directory.GetCurrentDirectory() + "\\AUT.exe";
                theform = LaunchApp(path, formName);

                Thread.Sleep(1000);

                Console.WriteLine("\nMoving Form1");
                Point pt = new Point(600, 200);
                SetFormPropertyValue(theform, "Location", pt);

                Console.WriteLine("\nGetting Form1 Location");
                Point lt = (Point)GetFormPropertyValue(theform, "Location");
                Console.WriteLine("X: " + lt.X.ToString() + " Y: " + lt.Y.ToString());

                Console.WriteLine("\nSetting TextBox to 'rock'");
                SetControlPropertyValue(theform, "textBox1", "Text", "rock");

                Console.WriteLine("\nSetting ComboBox to 'scissors'");
                SetControlPropertyValue(theform, "comboBox1", "Text", "scissors");

                Console.WriteLine("\nClicking button1");
                object[] parms = new object[] { null, EventArgs.Empty };
                InvokeMethod(theform, "button1_Click", parms);

                bool pass = true;

                Console.WriteLine("\nCheckint listBox1 for 'TextBox wins'");
                ListBox.ObjectCollection oc = (ListBox.ObjectCollection)GetControlPropertyValue(theform, "listBox1", "Items");

                string s = oc[0].ToString();
                if (s.IndexOf("TextBox wins") == -1)
                {
                    pass = false;
                }

                if (pass)
                {
                    Console.WriteLine("\n-- Scenario result = Pass --");
                }
                else
                {
                    Console.WriteLine("\n-- Scenario result = Fail --");
                }

                Console.WriteLine("\nClicking File->Exit in 3 Seconds");
                Thread.Sleep(3000);
                InvokeMethod(theform, "exitToolStripMenuItem_Click", parms);

                Console.WriteLine("\nEnd test scenario");
            }
            catch (System.Exception ex)
            {
                Console.WriteLine("Fatal error: " + ex.Message);
            }
           12. 编译生成测试程序并运行,OK,大功告成

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值