正则表达式是一种通过特殊的符号来匹配对应模式下的字符串的方法。QTP中常用的情形为以下四种:
1. 对象动态属性
自动化测试中,测试对象的识别举足轻重,一旦对象无法识别,整个测试就会失败。若某个对象的属性是动态的,我们就需要正则表达式来对此种动态属性进行参数化,这样就可以很好的避免动态属性变更导致对象无法识别的情况。
2. 相似对象的识别
比如一个页面上很多相似的对象,例如文本框,他们的name属性都很相似,可能只是最后一位的数字不同,此时就可以用正则表达式来描述。
3. 对象动态验证
在做某些对象属性验证时,若遇到动态的校验过程,最好的解决方式就是直接用正则表达式来匹配相应的动态属性值。例如验证对象的属性值为TestID_678,二后三位的数字是不定的,而是随机生成的,我们就可以通过TestID.*的方式来验证属性值进行匹配。
4. 复杂字符串长度
当处理一些非常复杂或较长字符串时,也可以使用正则表达式进行简化输入,从而降低输入错误风险,比如打开一个博客,该博客的名字很长,我们就可以用正则表达式取其前几个字符加上*来进行匹配,以避免输入过多造成的错误。
下面我们来看看具体应用:
举个QQ邮箱的例子,我们往对象库里先加入一个收件箱那个link的对象,我们看到后面有”(1)”这个状态的字符串。当然如果有两封未读,括号里的数字就是2了。
所以为了可以避免未读邮件数量的变化导致对象不能识别,我们来使用正则表达式。
点击上面红色圈里的button之后就会让你开始设置正则表达式了。QTP会自动帮你把特殊字符转化了,比较方便。这里我们将原先的”收件箱(1)” 修改成 ”收件箱\(.*\)”,然后再尝试着高亮显示对象,如果可以正确识别对象,那么说明已经成功了。
修改后的对象属性:
一旦建立好对象库并对动态对象属性进行正则化之后,就可以通过GetRoProperty函数来获取它的动态属性值了,我们来测试一下:
注意:这里我犯了一个小错误,第一遍执行的时候报了一个警告,稍微修改下就可以运行了。因为我没有考虑到如果全部为已读邮件的话,这条link就变成了”收件箱”了,没有括号了,我想大家应该知道怎么改吧~~
Set syBro = Browser("QQ邮箱").Page("QQ邮箱")
msg = syBro.Link("收件箱(1)").GetROProperty("text")
msgbox msg
正则表达式除了可以在对象库里进行动态属性匹配外,还可以在描述性编程中进行匹配。当在使用描述性编程时,可以直接用正则表达式来进行描述:
Set syLink = Description.Create
syLink("name").RegularExpression = True '打开正则表达式,其实默认就是True,可以省略
syLink("name") = "TestID.*"
下面来讲讲RegExp对象:
Vbs提供了针对正则表达式的一个非常实用的类,就是RegExp
Global属性:代表全局匹配
IgnoreCase属性:大小写忽略
Pattern属性:正则表达式
Execute方法:匹配搜索,返回匹配结果集合
Replace方法:匹配代替,返回替代匹配结果
Test方法:测试匹配,返回布尔类型
下面举几个实例:
'判断正则匹配是否正确
'msgbox (IsRegMatch("a123","http://www.123.456.com"))
Function IsRegMatch(patrn,str)
Dim regEx
Set regEx = New RegExp
regEx.Pattern = patrn
regEx.IgnoreCase = False
IsRegMatch = regEx.Test(str)
Set regEx = nothing
End Function
'替换匹配字符串
'msgbox (ReplaceRegMatch("9","loader runner 9.0, qtp 9.0","10"))
Function ReplaceRegMatch(patrn,str,replaceStr)
Dim regEx
Set regEx = New RegExp
regEx.Pattern = patrn
regEx.IgnoreCase = False
regEx.Global = True 'false的时候只会替换第一个匹配的字符串。若为true则会替换所有匹配的字符串
ReplaceRegMatch = regEx.Replace(str,replaceStr)
End Function
'返回匹配内容
'returnRegMatch "qtp .","qtp 1 qtp 2 qtp3 qtp 4"
Function ReturnRegMatch(patrn,str)
Dim regEx,matches,match
Set regEx = New RegExp
regEx.Pattern = patrn
regEx.IgnoreCase = true
regEx.Global = true '打开全局搜索
Set matches = regEx.Execute(str)
For Each match in matches
print cstr(match.firstIndex) + " " + match.value + " " + cstr(match.length)
Next
End Function
最后再来说说具体的应用。大家都知道WinList,WinComboBox,WebList等这些对象都是些直接可以进行选择的,接下来就是要通过正则表达式来模糊匹配这些对象中的list项,从而提高脚本的效率。我找了testdao网站的一个用户资料设置里的例子,这是个时区的选择,比较贴切:
可以看到,这个list里的选项很多,而且都是以(GMT +xxxx)开头的。
下面的function是用来实现模糊匹配list里的选项,如果匹配则选择该项。
Function SelectRegExp(Obj,patrn)
Dim numOfItems,i,CurrentValue,regEx,ItemToSelect,oldFilter
Set regEx = New RegExp
regEx.Pattern = patrn
regEx.IgnoreCase = False
oldFilter = Reporter.Filter
Reporter.Filter = 2
ItemToSelect = -1
NumOfItems = obj.GetRoProperty("items count")
for i=1 to NumOfItems
CurrentValue = Obj.GetItem(i) ‘注释1
If regEx.Test(CurrentValue) Then
If(ItemToSelect<>-1) then
SelectRegExp =-1 '项不唯一
Reporter.Filter = oldFilter
Exit Function
End If
ItemToSelect = i
End If
Next
Reporter.Filter = oldFilter
If(ItemToSelect>=0) Then
SelectRegExp = obj.Select(ItemToSelect - 1) ‘注释2
Else
SelectRegExp = -1
End If
End Function
测试一下:
首先要注册这个function,使用RegisterUserFunc,关于这个function参见帮助:
RegisterUserFunc "WebList","SelectRegExp","SelectRegExp"
Browser("个人资料 - 测试之道 - Powered").Page("个人资料 - 测试之道 - Powered").WebList("timeoffset").SelectRegExp("\(GMT -10:00\).*")
再加一点小注释:
细心的盆友一定发现了,注释1跟注释2不一样的地方,就是下标的表示上,说明了GetItem这个方法的下标是从1开始的,而Select方法的下标是从0开始的,所以在Select方法处我用了原来的坐标-1来作为下标,这点需要稍微注意下。