net自动化测试之道基于反射的UI自动化测试—获取Form的属性

Accessing Form Properties

Problem

You want to retrieve the properties of anapplication form object.

 问题

如何获取Form的属性呢?

Design

Use the Type.GetProperty()methodto get a reference to the property you want to examine.

Then use the PropertyInfo.GetValue()methodin conjunction with a method delegate to get

the value of the property.

设计

首先使用Type.GetProperty()方法获取我们想检测的属性的引用,然后用PropertyInfo.GetValue()方法结合代理获取该属性的值。

解决方案

if(theForm.InvokeRequired)

{

Delegate d=newGetFormPropertyValueHandler(GetFormPropertyValue);

object[]o=newobject[]{theForm,"Location"};

Point p=(Point)theForm.Invoke(d,o);

Console.WriteLine("Form1location="+p.X+""+p.Y);

}

else

{

Console.WriteLine("Unexpected logicflow");

}

在某处我们声明代理方法:

delegate objectGetFormPropertyValueHandler(Form f,

string propertyName);

static object GetFormPropertyValue(Formf,string propertyName)

{

Type t=f.GetType();

PropertyInfo pi=t.GetProperty(propertyName);

object result=pi.GetValue(f,null);

return result;

}

Comments

When performing lightweightreflection-based UI test automation,you may want to retrieve

properties of the application form such asthe Location and Size properties.This allows you to

verify the state of the Form object undertest and determine a test scenario pass/fail result.The

key to obtaining the value of a formproperty is to use the PropertyInfo.GetValue()method.

Unfortunately,there is a hidden issue—youshould not call GetValue()directly from a thread

that is not the main form thread.This issueis discussed in detail in“Section 2.2 Manipulating

Form Properties.”If the hidden issue didnot exist,you could get a form property like this:

注解

当执行基于反射的自动化UI测试的时候,我们可能想获取应用程序的属性,如Location、Size。这可以让我们验证被测Form对象的状态,并且确定测试结果。获取Form属性的值的关键是使用PropertyInfo.GetValue()。不幸的是有个隐藏问题,我们不能在非主form线程中直接调用该方法。这个问题在上一节讨论过。如果这个隐藏的问题不存在,我们可以这样获取form的属性:

string formName="AUT.Form1";

stringpath="..\\..\\..\\AUT\\bin\\Debug\\AUT.exe";

theForm=LaunchApp(path,formName);//seeSection 2.1

Type t=theForm.GetType();

PropertyInfopi=t.GetProperty("Location");

Point p=(Point)pi.GetValue(theForm,null);

Console.WriteLine("Form1location="+p.X+""+p.Y);

但是由于我们是在测试套件线程中调用GetValue()方法的,而不是在Form线程中,因此我们要用到代理,调用Form.Invoke():

if(theForm.InvokeRequired)

{

Delegate d=newGetFormPropertyValueHandler(GetFormPropertyValue);

object[]o=newobject[]{theForm,"Location"};

Point p=(Point)theForm.Invoke(d,o);

Console.WriteLine("Form1location="+p.X+""+p.Y);

}

else

{

Console.WriteLine("Unexpected logicflow");

}

在某处我们声明代理:

delegate objectGetFormPropertyValueHandler(Form f,

string propertyName);

static object GetFormPropertyValue(Formf,string propertyName)

{

Type t=f.GetType();

PropertyInfo pi=t.GetProperty(propertyName);

return pi.GetValue(f,null);

}

In short,you call Form.Invoke()with adelegate argument.Control of execution is

transferred to the delegate,which is inturn mapped to a helper method that calls the

PropertyInfo.GetValue()method.This strategy solves the Invoke()issue.You can signifi-

cantly increase the modularity of your testautomation by wrapping up the code in this

solution like this:

简言之,我们给Form.Invoke()方法传递一个代理,控制就会转移到代理,也就转到与之匹配的辅助方法PropertyInfo.GetValue()。这种策略解决了Invoke()的问题,封装这个解决方案中的代码,可以增加测试套件的模块性:

delegate objectGetFormPropertyValueHandler(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);

return iResult;

}

else

{

Type t=f.GetType();

PropertyInfo pi=t.GetProperty(propertyName);

object gResult=pi.GetValue(f,null);

return gResult;

}

}

然后这样调用:

Pointp=(Point)GetFormPropertyValue(theForm,"Location");

Console.WriteLine("Formlocation="+p.X+""+p.Y);

This GetFormPropertyValue()wrapperis a bit tricky because it is self-referential.When

called in the Main()method of your harness,InvokeRequiredis initially true,because the calling

thread does not own the form.Executionbranches to the Form.Invoke()statement,which,in

turn,calls theGetFormPropertyValueHandler()delegate that calls back into the associated

GetFormPropertyValue()method.But on the second pass through the wrapper,InvokeRequired

will be false because the call comes fromthe originating thread.Control transfers to the else part

of the logic,where the PropertyInfo.GetValue()retrievesthe form property.With this tech-

nique,you can retrieve the value of anyform property.For example:

这个封装的GetFormPropertyValue()方法有点难理解,因为它是自我引用的。当在我们的测试套件的Main()方法中调用的时候,InvokeRequired被初始化为true,因为当前线程不拥有这个form。因此程序运行至if分支,执行Form.Invoke()语句,该调用触发代理方法的调用,从而调用与代理关联的GetFormPropertyValue()。但是当第二次进入GetFormPropertyValue()方法的时候InvokeRequired变为false,因为调用发生在同一线程上。程序进入else分支,在这个分支中PropertyInfo.GetValue()将获取form的属性。使用这种方式我们可以获取form的任何属性。例如:

stringtitle=(string)GetFormPropertyValue(theForm,"Text");

Console.WriteLine("Formtitle="+title);

Sizesize=(Size)GetFormPropertyValue(theForm,"Size");

Console.WriteLine("Form size="+size.Height+"x"+size.Width);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值