GUI元素库:查找函数
QTP对于GUI对象查找的能力是相当之强的。这个通过Object Repository里属性设置就可以看出来。对于某一个特定的软件产品来说,其实并不需要所有的这些能力。设计GUI元素查找函数就是分析所有这个软件产品涉及到的GUI元素,把他们分门别类,针对每种类型设计相应的查找函数。
GUI元素查找函数底层都是使用描述性编程(Descriptive Programming)来查找GUI元素的。
我们通过一个实例来详细介绍这个GUI元素查找函数库。
查找函数
一个真实的对Web
Application测试的QTP
project,有下面一些查找函数
· GUI_Html_FindByTextAndTag(objContainer, strText,
strTag, xtype)
这个函数具有根据“inner
text”和“tag”来查找对象的能力
· GUI_Html_FindById(objContainer, strId, xtype)
这个函数具有根据ID属性来查找对象的能力
· GUI_Html_FindByName(objContainer, strName, xtype)
这个函数具有根据Name属性来查找对象的能力
· GUI_Html_FindFromObjRepo(objContainer, strName, xtype)
这个函数具有从Object
Repository查找对象的能力。存在极少的一些element,把它放到Object Repository里可能是更有效率的方式。
· GUI_Html_FindByLabel(objContainer, label, xtype)
这个函数具有根据Label来查找Input元素的能力。关于什么是label,请参考web方面的文档。前面例子的GEdit("Login
Name"),就是根据Label来查找Input元素的实例。
· GUI_Html_FindTableByColumns(objContainer, strColNames)
这个函数具有根据column name来查找Table的能力。实践表明,Table是一个经常会用到的GUI Element,而Column name是最能标识一个Table的(所见即所得风格)。
入口函数
作为一个封装良好的Library,并不需要把这么多接口统统暴露出来。实际上,这里还提供了一个总入口作为对外的接口。
GUI_Html_FindElement(objContainer, strMark, xtypye)
这个函数会根据xtype之不同,按照特定顺序调用上面的函数来查找一个GUI element,直到找到为止,或者返回Nothing表示没有找到。
作为设计者,你必须要明确每一种Element可能具有的查找方式,比如
link:id,name,textandtag,objrepo
webedit:id,name,label,objrepo
webtable:id, columns, objrepo
总的来说。外部程序只需要调用查找函数库的入口函数就可以完成绝大多数GUI element的查找。
Find与Get
如果你使用Object
Repository来定位GUI元素,QTP提供了一个很好的机制来提高代码的稳定性,它就是一个等待对象出现的机制。它的原理是这样,比如这样一行代码:
Browser("XXX").Page("YYY").WebEdit("loginform.:name").Set
"ABC"
如果执行到这里的时候,WebEdit("loginform.:name")还未出现(比如page还没有完全load),那么QTP会等待一段时间。只要在这个时间范围内,此元素在页面生成,就会顺利执行下去,而没有任何类似对象不存在的错误抛出。
但是对于GUI对象查找函数,这种机制是无效的,因为它使用Descriptive
Programming。所以有必要提供类似机制。在GUI元素查找库里提供了下面一个接口:
GUI_GetElement(objContainer, strMark, xtypye)
GUI_GetElement相对于与GUI_FindElement之不同在于,前者有一个timeout时间,如果在timeout时间之内没有找到GUI element,会抛出一个Error;而后者是马上返回,如果没有找到,返回Nothing。GUI_GetElement的实现像下面的样子
GUI_GETELEMENT_TIMEOUT=20
'seconds
Function
GUI_GetElement(objContainer, strMark, xtype)
Set ele = Nothing
for idx=0 to GUI_GETELEMEN_TIMEOUT
Set ele =
GUI_FindElement(objContainer, strMark, xtype)
if Not ele Is Nothing Then
Exit For
end if
Wait 1 'sleep 1 second
next
AssertNotNothing ele, "Failed to find
object with mark<"&strMark&">,
xtype<"&xtype&">"
End Function
Index标识
有时候在一个界面上,两个Element具有相同的标识。比如下面的例子,开始时间和结束时间都具有Day,Hour和Minute三个控件。
对于这种情况,就需要指定Input控件的序号,也就是所谓的“Index”。默认index是1,无需指定。如果index不是1,比如2,那么用“#2“来标识。比如得到第二个“Day”控件。
Set bjEndDay =
GUI_FindElement(objContainer, "Day#2", "JavaSpin")
使用Index标识带来一个问题,就是“#”成了特殊字符。如果你的标识符里碰巧有#,而且碰巧#后面是数字,那么需要用\来转义。其他情况都不需要转义,程序会把#解释为字面量而不是Index标识符。