映射机制的实现示例及介绍

using System;

using System.Management;

 

// This sample demonstrates invoking

// a WMI method using an array of arguments.

public class InvokeMethod

{   

    public static void Main()

    {

 

        // Get the object on which the

        // method will be invoked

        ManagementClass processClass =

            new ManagementClass("Win32_Process");

 

        // Create an array containing all

        // arguments for the method

        object[] methodArgs =

            {"notepad.exe", null, null, 0};

 

        //Execute the method

        object result =

            processClass.InvokeMethod(

            "Create", methodArgs);

 

        //Display results

        Console.WriteLine(

            "Creation of process returned: " + result);

        Console.WriteLine("Process id: " + methodArgs[3]);

    }

 

}

 

 

 ×××××××××××××××××××××××××

 

public   class   ClassA  
  {  
      public   void   func1(   ref   int   j   )  
      {  
          j++   ;  
      }      
  }  
  public   class   ClassB  
  {  
      public   void   func2()  
      {  
            int   j   ;  
            ClassA   A   =   new   ClassA()   ;  
            Type   tpClass   =   A.GetType()   ;  
            MethodInfo   miMethod   =   tpClass.GetMethod(   "func1"   )   ;  
            miMethod.Invoke(   A   ,   new   object[]{j}   )   ;     //
这里这样调用的话,返回的j并没有作相应   的改变,没有达到ref的效果;如果写成ref   j的话又有错误,该怎么写啊。  
      }  
  }

 

 

 

 

 

 

 

C#反射机制

 

转自:http://hi.baidu.com/wuzj/blog/item/ca4a848bcedafcd4fc1f1018.html

 

咏·才是牛人,今天让他帮我调了一下作业的代码,见识了,开眼界啦。。。这是他找出参照实现反射机制的例子,后面那个是我参照实现作业主体部分的例子。作业的主要内容是,利用反射机制,实现自动化测试,具体的就是获取textbox的text属性,激发button响应事件。

 

   反射的定义:审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等。
          System.reflection命名空间包含的几个类,允许你反射(解析)这些元数据表的代码   

System.Reflection.Assembly
System.Reflection.MemberInfo
System.Reflection.EventInfo
System.Reflection.FieldInfo
System.Reflection.MethodBase
System.Reflection.ConstructorInfo
System.Reflection.MethodInfo
System.Reflection.PropertyInfo
System.Type
以下是上面几个类的使用方法:
(1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。
(2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
(3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetConstructors或 GetConstructor方法来调用特定的构造函数。
(4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。
(5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。
(6)使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。
(7)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。
(8)使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。
反射的层次模型:

(注:层次间都是一对多的关系)

反射的作用:
1、可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型
2、应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射。
3、反射主要应用与类库,这些类库需要知道一个类型的定义,以便提供更多的功能。

应用要点:
1、现实应用程序中很少有应用程序需要使用反射类型
2、使用反射动态绑定需要牺牲性能
3、有些元数据信息是不能通过反射获取的
4、某些反射类型是专门为那些clr 开发编译器的开发使用的,所以你要意识到不是所有的反射类型都是适合每个人的。

 

反射appDomain 的程序集:

当你需要反射AppDomain 中包含的所有程序集,示例如下:
static void Main
{
       //通过GetAssemblies 调用appDomain的所有程序集
       foreach (Assembly assem in Appdomain.currentDomain.GetAssemblies())
      {
       //反射当前程序集的信息
            reflector.ReflectOnAssembly(assem)
      }
}

说明:调用AppDomain 对象的GetAssemblies 方法 将返回一个由System.Reflection.Assembly元素组成的数组。


反射单个程序集:

上面的方法讲的是反射AppDomain的所有程序集,我们可以显示的调用其中的一个程序集,system.reflecton.assembly 类型提供了下面三种方法:
1、Load 方法:极力推荐的一种方法,Load 方法带有一个程序集标志并载入它,Load 将引起CLR把策略应用到程序集上,先后在全局程序集缓冲区,应用程序基目录和私有路径下面查找该程序集,如果找不到该程序集系统抛出异常
2、LoadFrom 方法:传递一个程序集文件的路径名(包括扩展名),CLR会载入您指定的这个程序集,传递的这个参数不能包含任何关于版本号的信息,区域性,和公钥信息,如果在指定路径找不到程序集抛出异常。
3、LoadWithPartialName:永远不要使用这个方法,因为应用程序不能确定再在载入的程序集的版本。该方法的唯一用途是帮助那些在.Net框架的测试环节使用.net 框架提供的某种行为的客户,这个方法将最终被抛弃不用。

注意:system.AppDomain 也提供了一种Load 方法,他和Assembly的静态Load 方法不一样,AppDomain的load 方法是一种实例方法,返回的是一个对程序集的引用,Assembly的静态Load 方发将程序集按值封装发回给发出调用的AppDomain.尽量避免使用AppDomain的load 方法


利用反射获取类型信息:

前面讲完了关于程序集的反射,下面在讲一下反射层次模型中的第三个层次,类型反射
一个简单的利用反射获取类型信息的例子:

using system;
using sytem.reflection;
class reflecting
{
       static void Main(string[]args)
       {
             reflecting reflect=new reflecting();//定义一个新的自身类
             //调用一个reflecting.exe程序集

             assembly myAssembly =assembly.loadfrom(“reflecting.exe”)
             reflect.getreflectioninfo(myAssembly);//获取反射信息
       }

       //定义一个获取反射内容的方法
       void getreflectioninfo(assembly myassembly)
       {
             type[] typearr=myassemby.Gettypes();//获取类型
             foreach (type type in typearr)//针对每个类型获取详细信息
            {
                   //获取类型的结构信息
                  constructorinfo[] myconstructors=type.GetConstructors;

                 //获取类型的字段信息
                 fieldinfo[] myfields=type.GetFiedls()

                 //获取方法信息
                 MethodInfo   myMethodInfo=type.GetMethods();

                 //获取属性信息
                 propertyInfo[] myproperties=type.GetProperties

                 //获取事件信息
                 EventInfo[] Myevents=type.GetEvents;
           }
      }
}
其它几种获取type对象的方法:
1、System.type   参数为字符串类型,该字符串必须指定类型的完整名称(包括其命名空间)
2、System.type 提供了两个实例方法:GetNestedType,GetNestedTypes
3、Syetem.Reflection.Assembly 类型提供的实例方法是:GetType,GetTypes,GetExporedTypes
4、System.Reflection.Moudle 提供了这些实例方法:GetType,GetTypes,FindTypes


设置反射类型的成员:

反射类型的成员就是反射层次模型中最下面的一层数据。我们可以通过type对象的GetMembers 方法取得一个类型的成员。如果我们使用的是不带参数的GetMembers,它只返回该类型的公共定义的静态变量和实例成员,我们也可以通过使用带参数的 GetMembers通过参数设置来返回指定的类型成员。具体参数参考msdn 中system.reflection.bindingflags 枚举类型的详细说明。

例如:
//设置需要返回的类型的成员内容
bindingFlags bf=bingdingFlags.DeclaredOnly|bingdingFlags.Nonpublic|BingdingFlags.Public;
foreach (MemberInfo mi int t.getmembers(bf))
{
       writeline(mi.membertype)    //输出指定的类型成员
}


通过反射创建类型的实例:

通过反射可以获取程序集的类型,我们就可以根据获得的程序集类型来创建该类型新的实例,这也是前面提到的在运行时创建对象实现晚绑定的功能
我们可以通过下面的几个方法实现:
1、System.Activator 的CreateInstance方法。该方法返回新对象的引用。具体使用方法参见msdn
2、System.Activator 的createInstanceFrom 与上一个方法类似,不过需要指定类型及其程序集
3、System.Appdomain 的方法:createInstance,CreateInstanceAndUnwrap,CreateInstranceFrom和CreateInstraceFromAndUnwrap
4、System.type的InvokeMember实例方法:这个方法返回一个与传入参数相符的构造函数,并构造该类型。
5、System.reflection.constructinfo 的Invoke实例方法

反射类型的接口:

如果你想要获得一个类型继承的所有接口集合,可以调用Type的FindInterfaces GetInterface或者GetInterfaces。所有这些方法只能返回该类型直接继承的接口,他们不会返回从一个接口继承下来的接口。要想返回接口的基础接口必须再次调用上述方法。


反射的性能:

使用反射来调用类型或者触发方法,或者访问一个字段或者属性时clr 需要做更多的工作:校验参数,检查权限等等,所以速度是非常慢的。所以尽量不要使用反射进行编程,对于打算编写一个动态构造类型(晚绑定)的应用程序,可以采取以下的几种方式进行代替:
1、通过类的继承关系。让该类型从一个编译时可知的基础类型派生出来,在运行时生成该类型的一个实例,将对其的引用放到其基础类型的一个变量中,然后调用该基础类型的虚方法。
2、通过接口实现。在运行时,构建该类型的一个实例,将对其的引用放到其接口类型的一个变量中,然后调用该接口定义的虚方法。
3、通过委托实现。让该类型实现一个方法,其名称和原型都与一个在编译时就已知的委托相符。在运行时先构造该类型的实例,然后在用该方法的对象及名称构造出该委托的实例,接着通过委托调用你想要的方法。这个方法相对与前面两个方法所作的工作要多一些,效率更低一些。

 

个人操作方案:

源DLL类:

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.UI;
using System.Collections;


namespace cn.SwordYang
{

    public class TextClass:System.Web.UI.Page
    {

public static void RunJs(Page _page, string Source)
        {
            _page.ClientScript.RegisterStartupScript(_page.GetType(), "", "<script type=/"text/javascript/">" + Source + ";</script>");

        }

}

}

 

//调用代码

System.Reflection.Assembly ass = Assembly.LoadFrom(Server.MapPath("bin/swordyang.dll")); //加载DLL
            System.Type t = ass.GetType("cn.SwordYang.TextClass");//获得类型
            object o = System.Activator.CreateInstance(t);//创建实例

            System.Reflection.MethodInfo mi = t.GetMethod("RunJs");//获得方法


            mi.Invoke(o, new object[] { this.Page,"alert('测试反射机制')"});//调用方法

 

 

反射机制对应设计模式中的策略模式

 

 

 

 

 

 

 

××××××××××××××××××××××××××

 http://book.csdn.net/bookfiles/783/10078323529.shtml

 

 

 

 

3.3  自动化测试工具的原理

测试工具的优势在于可部分地替代人工的测试过程,能重复不断地执行,能精确判断数值和字符对象。自动化测试工具把测试用例用自动的方式执行,例如,自动地产生数据,自动地打开应用程序,自动地查找控件,自动地输入数据,自动地操作控件,自动地收集测试结果,自动地与预期结果进行比较等。

自动化功能测试工具可基于GUI层面进行测试,也可基于代码层面进行测试。只要实现了自动化执行测试用例,自动化地检查测试数据的测试工具,替代人工进行测试步骤的执行,从而验证应用程序是否满足了特定功能的测试工具,都可以称为自动化功能测试工具。

3.3.1  基于代码层面的功能自动化测试工具

基于代码层面的功能自动化测试工具主要是一些单元测试工具,例如JUnit、NUnit、MSTest等,这些工具直接访问被测试的应用程序的代码,对其中的类和函数进行调用,输入各种测试数据,检查函数的返回值,通过比较返回值与期待的值是否一致来判断测试是否通过。图3.2所示的是Visual Studio.NET 2005中的单元测试管理界面。

图3.2  Visual Studio.NET 2005中的单元测试管理界面

这种类型的工具主要实现了测试代码框架产生的自动化,例如,下面代码是Visual Studio.NET 2005中的单元测试框架MSTest为某个类的方法自动产生的单元测试代码框架:

// 以下代码由 Microsoft Visual Studio 2005 生成。

// 测试所有者应该检查每个测试的有效性。

using Microsoft.VisualStudio.TestTools.UnitTesting;

using System;

using System.Text;

using System.Collections.Generic;

using AUT;

namespace TestProject1

{

    /// <summary>

    ///这是 AUT.Form1 的测试类,旨在包含所有 AUT.Form1 单元测试

    ///</summary>

    [TestClass()]

    public class Form1Test

    {

        private TestContext testContextInstance;

        /// <summary>

        ///获取或设置测试上下文,上下文提供有关当前测试运行及其功能的信息。

        ///</summary>

        &Context

            actual = accessor.Add(i, j);

            Assert.AreEqual(expected, actual, "AUT.Form1.Add 未返回所需的值。");

            Assert.Inconclusive("验证此测试方法的正确性。");

        }

    }

}

在代码框架的背后,单元测试框架负责查找和调用被测试的类和方法,通过代码反射机制可以访问到被测试代码中的所有方法和属性。另外,单元测试框架会提供一系列的Assert类,使用这些Assert类可以简化测试结果检查、判断的工具。

提示在执行单元测试时,单元测试框架负责加载包含测试类的程序集文件,通过查找里面的测试类和测试方法标识来加载测试方法,例如,上面代码中的“[TestMethod()]”就是用于标识其中的测试方法。

3.3.2  基于浏览器和DOM对象模型的功能自动化测试工具

另外一种自动化的功能测试工具是基于浏览器和DOM对象模型开发的,例如Selenium、Watir等,这些测试工具直接访问Web浏览器,利用脚本语言操纵浏览器和Web页面中包含的DOM对象,从而达到模拟用户控制浏览导航、页面元素的操纵等效果,并且直接获取DOM对象的属性,从而获得Web页面元素的各种属性,通过这些属性可判断测试步骤的结果是否正确。图3.3所示的是可作为插件嵌入到Mozilla Firefox浏览器中的Selenium IDE的测试界面。

图3.3  Selenium IDE的测试界面

HTML DOM(Document Object Model)是一个HTML文档的编程接口,它定义了HTML的标准对象集合,并且定义了标准的访问和操纵HTML对象的方式。HTML DOM接口让测试人员可以访问和操纵HTML文档的内容。图3.4所示的界面是使用了一个名为“IE DOM Inspector”的工具查看到的Web页面中的DOM对象。

图3.4  IE DOM Inspector的界面

如果熟悉和了解DOM的原理,那么完全可以自己动手编写一个基于浏览器和DOM的Web页面自动化测试工具,例如,下面的C#代码就是一个简单的例子:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Diagnost   //[TestInitialize()]

        //public void MyTestInitialize()

        //{

        //}

        //

        //使用 TestCleanup 在运行完每个测试后运行代码

        //

        //[TestCleanup()]

        //public void MyTestCleanup()

        //{

        //}

        //

        #endregion

        /// <summary>

        ///Add (int, int) 的测试

        ///</summary>

        [DeploymentItem("AUT.exe")]

        [TestMethod()]

        public void AddTest()

        {

            Form1 target = new Form1();

            TestProject1.AUT_Form1Accessor accessor =
new TestProject1.AUT_Form1Accessor(target);

            int i = 0; // TODO: 初始化为适当的值

            int j = 0; // TODO: 初始化为适当的值

            int expected = 0;

            int actual;

            actual = accessor.Add(i, j);

            Assert.AreEqual(expected, actual, "AUT.Form1.Add 未返回所需的值。");

            Assert.Inconclusive("验证此测试方法的正确性。");

        }

    }

}

在代码框架的背后,单元测试框架负责查找和调用被测试的类和方法,通过代码反射机制可以访问到被测试代码中的所有方法和属性。另外,单元测试框架会提供一系列的Assert类,使用这些Assert类可以简化测试结果检查、判断的工具。

提示在执行单元测试时,单元测试框架负责加载包含测试类的程序集文件,通过查找里面的测试类和测试方法标识来加载测试方法,例如,上面代码中的“[TestMethod()]”就是用于标识其中的测试方法。

3.3.2  基于浏览器和DOM对象模型的功能自动化测试工具

另外一种自动化的功能测试工具是基于浏览器和DOM对象模型开发的,例如Selenium、Watir等,这些测试工具直接访问Web浏览器,利用脚本语言操纵浏览器和Web页面中包含的DOM对象,从而达到模拟用户控制浏览导航、页面元素的操纵等效果,并且直接获取DOM对象的属性,从而获得Web页面元素的各种属性,通过这些属性可判断测试步骤的结果是否正确。图3.3所示的是可作为插件嵌入到Mozilla Firefox浏览器中的Selenium IDE的测试界面。

图3.3  Selenium IDE的测试界面

HTML DOM(Document Object Model)是一个HTML文档的编程接口,它定义了HTML的标准对象集合,并且定义了标准的访问和操纵HTML对象的方式。HTML DOM接口让测试人员可以访问和操纵HTML文档的内容。图3.4所示的界面是使用了一个名为“IE DOM Inspector”的工具查看到的Web页面中的DOM对象。

图3.4  IE DOM Inspector的界面

如果熟悉和了解DOM的原理,那么完全可以自己动手编写一个基于浏览器和DOM的Web页面自动化测试工具,例如,下面的C#代码就是一个简单的例子:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Diagnostics;

using System.Threading;

// 引用Microsoft.mshtml的HTML接口

using mshtml;

// 引用IE对象

using SHDocVw;

namespace WebAutomatedTest1

{

    public partial class Form1 : Form

    {

        static AutoResetEvent documentComplete = new AutoResetEvent(false);

        public Form1()

        {

            InitializeComponent();

        }

        private void button1_Click(object sender, EventArgs e)

        {

            InternetExplorer ie = null;

            // 启动IE的进程

            Process p = Process.Start("iexplore.exe", "about:blank");

            // 等待一段时间,让IE启动

            Thread.Sleep(3000);

            if (p == null)

            {

                MessageBox.Show("不能启动IE!");

                return;

            }

            SHDocVw.ShellWindows allBrowsers = new SHDocVw.ShellWindows();

            // 附加到IE进程

            int i = 0;

            while (i < allBrowsers.Count && ie == null)

            {

                InternetExplorer browser = (InternetExplorer)allBrowsers.Item(i);

                if (browser.HWND == (int)p.MainWindowHandle)

                    ie = browser;

                ++i;

            }

            if (ie == null)

            {

                MessageBox.Show("不能附加到IE!");

                return;

            }

            ie.DocumentComplete +=
new DWebBrowserEvents2_DocumentCompleteEventHandler(ie_DocumentComplete);

            object nil = new object();

            ie.Navigate("http://127.0.0.1:9462/WebUT/default.aspx",
ref nil,ref nil,ref nil,ref nil);

            documentComplete.WaitOne();

            HTMLDocument Doc = (HTMLDocument)ie.Document;

            HTMLInputElement textBox =
(HTMLInputElement)Doc.getElementById("TextBox1");

            textBox.value = "123";

            HTMLInputElement button =
(HTMLInputElement)Doc.getElementById("Button1");

            button.click();

            // 验证,如果Label1的值等于123,则表示测试通过

            HTMLSpanElement label =
(HTMLSpanElement)Doc.getElementById("Label1");

            if (label.innerText == "123")

            {

                MessageBox.Show("测试通过!");

            }

            else

            {

                MessageBox.Show("测试不通过!");

            }

        }

        private static void ie_DocumentComplete(object pDisp, ref object URL)

        {

            documentComplete.Set();

        }

    }

}

3.3.3  基于GUI对象识别的测试工具原理

目前,大部分自动化功能测试工具,尤其是商业的测试工具,都是基于GUI对象识别技术来设计的。基于GUI层面的测试需要与各种界面元素打交道,而且不同的编程语言和开发工具开发的应用程序在界面的表现、事件的响应上都略有不同,因此,设计基于GUI层面的自动化功能测试工具会更为复杂些。

Windows的API中封装了很多可用于自动化测试编程的函数,例如FindWindow、GetWindowRect等函数。这些函数可在编程语言或脚本代码中进行调用,从而实现自动化测试编程。例如,下面的C#代码封装了user32.dll中的FindWindow函数, 实现查找指定类型和名称的控件的功能:

using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.InteropServices;

namespace LowLevelGUITest

{

    public class Automation

    {

        // 引入user32.dll中的FindWindow函数

        [DllImport("user32.dll", CharSet = CharSet.Auto)]

        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        // 查找控件方法

        public IntPtr FindControl(string ClassName,string ControlName)

        {

            // 返回控件句柄

            return FindWindow(ClassName, ControlName);

        }

    }

}

可用下面的C#代码来调用这个封装的函数:

     private void button1_Click(object sender, EventArgs e)

     {

         Automation automation = new Automation();

         // 查找名为AUT的窗体

         IntPtr p =
automation.FindControl("WindowsForms10.Window.8.app.0.378734a","AUT");

         // 判断是否找到控件

         if (p == IntPtr.Zero)

         {

             Console.WriteLine("找不到指定的控件!");

         }

     }

如果想进一步了解GUI对象识别的原理,可以打开Visual Studio.NET 2005自带的Spy++,如图3.5所示。

图3.5  Spy++的界面

Spy++中的搜索查找控件功能就是这种对象识别原理的体现。例如,在图3.6所示的界面中,可以看到某个指定的窗口的句柄、标题、类。

图3.6  Spy++中的搜索查找控件功能

3.3.4  反射机制在自动化功能测试工具中的使用

提示在基于GUI对象识别和控制的自动化测试工具中,过去一直依赖于Windows API函数的调用。而随着新的编程语言和平台的出现,涌现了很多新的语言特性,这些语言特性可用于自动化测试工具的设计,例如反射机制就是其中一项技术。

程序集包括模块,模块包含类型,类型包含成员。在.NET和Java中,都提供了反射的机制,反射提供了封装程序集、模块和类型的对象,可以通过反射动态地创建类型的实例,将类型绑定到现有对象,或者从现有对象中获取类型,然后调用类型的方法或访问其字段和属性。

反射机制可被用在测试中,通过反射来加载被测试程序,获取被测试程序的各种属性,触发被测试程序的各种事件,从而达到自动化测试的目的。例如,下面的C#代码通过反射机制读取程序中textBox1控件的Text属性:

        // 获取控件属性

        static object GetControlPropertyValue(string controlName,
string propertyName)

        {

            if (AUTForm.InvokeRequired)

            {

                Thread.Sleep(1000);

                return AUTForm.Invoke
(new GetControlPropertyValueHandler(GetControlPropertyValue),
new object[] { controlName, propertyName });

            }

            // 获取类型

            Type t1 = AUTForm.GetType();

            // 获取类型中的成员

            FieldInfo fi = t1.GetField(controlName, BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);

            object ctrl = fi.GetValue(AUTForm);

            Type t2 = ctrl.GetType();

            // 获取成员中的属性

            PropertyInfo pi = t2.GetProperty(propertyName, BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);

            // 返回控件属性值

            return pi.GetValue(ctrl, new object[0]);

        }

        delegate object GetControlPropertyValueHandler(string controlName, string propertyName);

而下面的C#代码则通过反射机制调用控件的方法,模拟用户点击按钮的过程:

        // 模拟用户点击按钮

        InvokeMethod("button1_Click", new object[] { null, new EventArgs() });

        // 调用控件方法

        static void InvokeMethod(string methodName, params object[] parms)

        {

            if (AUTForm.InvokeRequired)

            {

                Thread.Sleep(1000);

                AUTForm.Invoke(new InvokeMethodHandler(InvokeMethod),
new object[] { methodName, parms });

                return;

            }

            // 获取类型

            Type t = AUTForm.GetType();

            // 获取类型中的指定方法

            MethodInfo mi = t.GetMethod(methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;

            // 调用方法

            mi.Invoke(AUTForm, parms);

        }

       delegate void InvokeMethodHandler(string methodName, params object[] arms);

3.3.5  UI Automation在自动化功能测试工具中的使用

随着.NET 3.0和Vista的发布,微软提供了一套崭新的Windows界面框架,名为“UI Automation”,UI Automation在所有支持Windows Presentation Foundation(WPF)的操作系统中都可以使用。

UI Automation提供了一套对Windows界面的可编程的访问机制,同时也为测试自动化工具提供了一个新的思路。例如,在使用QTP的.NET插件对WPF控件进行测试时,就可以使用AutomationElement来访问控件属性,再例如,下面脚本通过AutomationElement访问Test4窗体控件的Name属性:

'通过AutomationElement访问控件属性

msgbox WpfWindow("Test4").AutomationElement.Current.Name

3.3.6  QTP对象识别技术

有了前面的基础,就不难理解QTP的工作原理了。QTP同样是通过查找应用程序界面中的各个控件的属性来判断是否与测试对象匹配,例如QTP中提供的“Object Spy”功能,就可以把某个界面控件的基本属性列举出来,如图3.7所示。

另外,还可以根据控件的类型,把其拥有的可操作的方法列举出来,如图3.8所示。

针对不同平台和语言编写的控件,QTP会采用不同的对象识别方法,但是共通的一点是,通过查找对象属性,依据该控件与其他控件能区分的属性来判断其身份,例如控件的类名、控件的文本等。QTP中的“Object Identification”界面中提供了一个可供测试员调整的对象识别配置器,如图3.9所示。

    

图3.7  QTP的“Object Spy”功能     图3.8  使用“Object Spy”查看控件可操作的方法

图3.9  QTP的“Object Identification”界面

提示其中“Mandatory Properties”中的属性是强制性的判断准则,“Assistive Properties”中的属性用于辅助性地判断。

单击“Add/Remove”按钮,可在如图3.10所示的界面中添加更多的属性用于唯一地标识和区别某个控件实例。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值