|
QTP中使用描述性编程
● 使用编程性描述(Using Programmatic Descrīptions)
在录制脚本时,QTP会将被测对象添加到对象仓库中。只要对象存在于仓库中,我们就可以在专家视图中使用该对象进行手动添加脚本。在脚本中,我们一般都使用对象的名称(该对象名称不区分大小写)作为对象描述。
例如:
在下面的语句中“username”是一个编辑框的名称。这个编辑框位于某页面(Page)之上(该页面的名称为“Mercury Tours”),并且该页面属于名为“Mercury Tours”的浏览器(browser)。
Browser("Mercury Tours").Page("Mercury Tours").WebEdit("username")
因为对象仓库中的对象的名称是唯一的,因此你只要在脚本中指定对象的名称即可。QTP根据指定的对象名称以及它的父对象在对象仓库中找到该对象,然后根据仓库中对象的详细描述从被测试程序中查找并识别对象。
其实,在QTP脚本中,不使用对象仓库或对象名称,也可以对被测程序中的对象进行操作。为了做到这一点,我们需要在QTP脚本中提供对象的属性及其值的列表。这就是编程性描述。
当对象不存在于对象仓库之中,而我们又希望操作该对象时,编程性描述就非常有用。如果有多个对象,它们具有某些相同的属性,通过编程性描述,我们可以在这些对象上进行相同的操作;或者某个对象的属性无法确定,需要在运行过程中指定,我们也可以使用编程性描述,来对该对象进行操作。
例如:在一个页面有多个check box,你不能预知其个数,也不知道所有check box的准确描述,然而你希望选中所有的check box。在这种情况下,你可以使用编程性描述来解决。你只需要让QTP对所有描述为HTML TAG=input,TYPE=check box的对象执行一个Set “ON”的操作即可。
编程性描述的方法有两种:
方法一:在语句中直接列出对象的属性及值的列表;
方法二:使用Descrīption对象,为Descrīption对象添加属性及值的集合,然后在语句中直接使用Descrīption对象的名称即可。
使用第一种方法要简单一些,但是在很多情况下,第二种方法更显得功能强大并更有效率。
● 在语句中直接使用编程描述(Entering Programmatic Descrīptions Directly into Statements)
在语句中不使用对象的名称,而是使用对象的描述(指定多对property:=value值)。
通常语法如下:
TestObject(“PropertyName1:=PropertyValue1”,“…”,“PropertyNameX:=PropertyValueX”)
TestObject:指的是测试对象的类名
PropertyName:=PropertyValue:指的是测试对象的属性及值。每对property:=value用双引号标记,并用逗号隔开。
注:property value可以是变量。
注意:在编程性描述中,QTP将所有的property value视为正则表达式。因此,当property value中包括正则表达式特殊字符(如*,?,或+)时,要在特殊字符前加“\”。
下面的语句中,使用到了Mercury Tours网页中的一个WebEdit对象,它的Name为Author,Index为3。在运行过程中,QTP就会从网页中查找Name为Author并且Index为3的WebEdit对象,并在WebEdit中输入文字“MarkTwain”。
Browser("Mercury Tours").Page("Mercury Tours").WebEdit("Name:=Author", "Index:=3").Set "Mark Twain"
注意:如果你对测试对象层级关系中的某个上级对象使用了编程性描述,那么在同一语句中,从该对象开始,它的所有下级对象都必须使用编程性描述,否则QTP不能识别该父级对象的下级对象。
例如:语句中,层级关系中所有的对象都使用了编程性描述:
Browser("Title:=Mercury Tours").Page("Title:=Mercury Tours").WebEdit("Name:=Author", "Index:=3").Set "Mark Twain"
下面的语句中,从层级关系中的某个点开始,使用编程性描述(从Page对象开始):
Browser("Mercury Tours").Page("Title:=Mercury Tours").WebEdit("Name:=Author", "Index:=3").Set "Mark Twain"
但是,你不能象下面的语句这样使用编程性描述。(它对Browser及Page对象使用了编程性描述,但是对于WebEdit对象,却又想使用对象仓库中的名称)
Browser("Title:=Mercury Tours").Page("Title:=Mercury Tours").WebEdit("Author").Set "Mark Twain"
QTP偿试根据WebEdit的名称在仓库中定位对象,但是却无法在仓库中找到它的父对象。
For more information on working with test objects, seeWorking with Test Objects。
如果在脚本中你要多次使用到相同的编程性描述,可以将对象指定到变量。
例如,有如下脚本:
Window("Text:=Myfile.txt - Notepad").Move 50, 50
Window("Text:=Myfile.txt - Notepad").WinEdit("AttachedText:=Find what:").Set "hello"
Window("Text:=Myfile.txt - Notepad").WinButton("Caption:=Find next").Click
你可以将脚本改进为:
Set MyWin = Window("Text:=Myfile.txt - Notepad")
MyWin.Move 50, 50
MyWin.WinEdit("AttachedText:=Find what:").Set "hello"
MyWin.WinButton("Caption:=Find next").Click
你还可以使用With语句,将脚本改进为:
With Window("Text:=Myfile.txt - Notepad")
.Move 50, 50
.WinEdit("AttachedText:=Find what:").Set "hello"
.WinButton("Caption:=Find next").Click
End With
For more information about theWithstatement, seeWith Statement。
● 在编程性描述中使用Descrīption对象(Using Descrīption Objects for Programmatic Descrīptions)
你可以使用Descrīption对象,来返回一个Properties collection对象,该集合对象包括一系列Property对象。每个Property对象由Property name及value组成。
然后在语句中用Properties collection对象替代被测对象的名称。
注意:默认情况下,所有被添加到Properties collection中的Property对象的值被当成正则表达式对待。因此,当Property Value中包含正则表达式的特殊字符(如*,?,+)时,要在特殊字符前使用“\”符号。
你也可以在Properties Collection中,将RegularExpression属性值设置为False,这样即使在Property Value中用到了正则表达式的特殊字符,也会被视为普通字符。更多信息参考QuickTest Professional Object Model Reference的Utility部分。
要创建Properties collection,使用Dexcription Create语句,语法如下:
SetMyDescrīption= Descrīption.Create()
一旦创建了Properties对象(例如上例中的Mydescrīption),在运行过程中,你就可以使用语句向Properties对象添加、编辑、移除或获取属性及属性值。这使你在运行过程中可以动态的决定:在对象描述中使用哪些属性、使用多少属性。
当你将一系列的属性及属性值加入到Properties collection中以后,你就可以在脚本语句中用Properties对象替代被测对象的名称。
例如,有如下语句:
Window("Error").WinButton("text:=OK", "width:=50").Click
通过改造,成为:
Set MyDescrīption = Descrīption.Create()
MyDescrīption("text").Value = "OK"
MyDescrīption("width").Value = 50
Window("Error").WinButton(MyDescrīption).Click
注:当为一个ActiveX对象创建编程性描述时,如果该对象的run-time对象是windowless的(即没有相应的window handel),就必须在属性描述中将它的windowless property设置为Ture。
例如:
Set ButDesc = Descrīption.Create
ButDesc("ProgId").Value = "Forms.CommandButton.1"
ButDesc("Caption").Value = "OK"
ButDesc("Windowless").Value = True
Window("Form1").AcxButton(ButDesc).Click
● 对WebElement对象使用编程性描述(Using Programmatic Descrīptions for the WebElement Object)
如果没有录制WebElement对象,也可以使用编程性描述,来对Web网站中的任何一个WebElement对象进行操作。
例如:
Browser("Mercury Tours").Page("Mercury Tours").WebElement("Name:=UserName", "Index:=0").Click
或
set WebObjDesc = Descrīption.Create()
WebObjDesc("Name").Value = "UserName"
WebObjDesc("Index").Value = "0"
Browser("Mercury Tours").Page("Mercury Tours").WebElement(WebObjDesc).Click
QuickTest clicks on the first Web object in the Mercury Tours page with the nameUserName。
关于WebElement对象的更多信息,参考QuickTest Professional Object Model Reference。
● 在编程性描述中使用Index属性(Using the Index Property in Programmatic Descrīptions)
在需要唯一识别一个对象时,index属性有时候可能非常有用。index属性是对象在源代码中出现的顺序,第1次出现时,index值为0。
Index属性是object-specific的。因此,当你用index属性值“3”来描述一个WebEdit对象时,QTP会在被测程序的当前页面中查找第4个WebEdit对象。
如果你使用index属性值3来描述一个WebElement对象时,QTP会在被测程序的当前页面中查找第4个Web对象。
例如,当前页面中存在下面的对象:
* 一个名为Qpple的Image对象
* 一个名为UserName的Image对象
* 一个名为UserName的WebEdit对象
* 一个名为Password的Image对象
* 一个名为Password的WebEdit对象
下面的语句中指的是列表中的第3个对象,因为它要求指向的是第1个名为UserName的WebEdit对象。
WebEdit("Name:=UserName", "Index:=0")
下面的语句中指的是列表中的第2个对象,因为它要求指向的是第1个名为UserName的WebElement对象。
WebElement("Name:=UserName", "Index:=0")
注:如果当前只有一个对象,使用index=0将无法查找到对象,因此就不能在对象描述中使用index属性。 |
|