正則表達式是一種通過特殊的符號來匹配對應模式下的字符串的方法。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來作為下標,這點需要稍微注意下。
