QTP里的DOM應用
DOM全稱”Document Object Model”,字面上叫做”文檔對象模型”,它是一款主要用于Web Html中的一種獨立語言。Html Dom主要通過定義一套標準的對象通道接口,使得我們能夠輕松訪問并控制Html對象元素,它是一種用于Html和Xml文檔的編程接口。DOM的表現方 法是一種樹狀結構。
有些時候QTP只對標準控件支持比較好,而對特殊的控件無法識別。DOM是一種罪底層的對象操作模型,使用它來控制對象不但速度快,而且可以訪問很多QTP無法訪問的東西。
1. 修改控件自身接口
QTP本身無法修改控件自身接口屬性,但通過DOM我們可以訪問并修改自身接口屬性
2. DOM對象下CurrentStyle對象應用
CurrentStyle是一個可以與Html對象元素style sheets進行交互的接口,它可以獲取對象元素的字體名,字體大小,顏色,是否可見等,在驗證點時有重要作用。
3. 性能提升
DOM執行速度會比QTP對象庫的執行速度快好幾倍,這是因為DOM是底層對象接口,而QTP首先要把對象封裝,然后在腳本運行時調用對象庫的對象,最后與頁面上的對象進行比對,如果匹配才可控制測試對象。而DOM是直接找對象進行控制。
下面的例子是IE對象模型里的DOM應用
1. 啟動IE的三種常見方法
在QTP中啟動IE:
SystemUtil.Run “iexplore.exe”
2. 使用WSH啟動IE:
Set oShell = CreateObject(“wscript.shell”)
3. 使用IE COM對象:
Set oIE = CreateObject("InternetExplorer.Application")
oIE.Visible = True
oIE.Navigate http://www.baidu.com
使用第三種方法還可以獲得當前窗口的句柄,并通過QTP來定位瀏覽器:
ieHwnd = oIE.HWND
Browser(“hwnd:=” & ieHwnd).Close
接下來的這個例子就是使用到DOM去操作頁面元素了
Set oIE = CreateObject("InternetExplorer.Application")
oIE.Visible = True
oIE.Navigate "http://www.baidu.com"
'While oIE.Busy
'Wend
oIE.Document.f.wd.value = "sunyu"
我把While oIE.Busy:Wend這兩句話注釋掉了,運行結果如下:
程序運行出錯了,主要是因為我們沒有等待頁面加載完,就進行了下一步的填值操作,QTP會找不到這個對象。如果你點擊Retry再次運行,那么這次會通過,因為頁面已經加載完畢了。所以我們在操作Web對象時,要特別注意需要等待頁面加載完畢。
注:以上這個錯誤我們會經常遇到,有時候你只需要關掉QTP再重新打開后就不會再遇到這個錯誤了。
遍歷所有IE對象:
Function EnumIE()
Set EnumIE = CreateObject("Scripting.Dictionary")
Set winShell = CreateObject("Shell.Application")
Set allWins = winShell.Windows
For each win in allWins
If instr(1,win.FullName,"iexplore.exe",vbTextCompare) Then
EnumIE.Add win.hwnd,win
End If
Next
End Function
我打開一共兩個IE窗口,但是第一個IE窗口里有四個子窗口,如下圖:
然后調用上面的代碼:
Set allIE = EnumIE()
For each oIE in allIE.Items
oIE.quit
Next
結果QTP報錯了
這是因為在同一個窗口下的四個子窗口使用的是同一個句柄,所以無法加入到Dictionary對象里去。只要對代碼稍加修改就可以了:
Function EnumIE()
Set EnumIE = CreateObject("Scripting.Dictionary")
Set winShell = CreateObject("Shell.Application")
Set allWins = winShell.Windows
For each win in allWins
If instr(1,win.FullName,"iexplore.exe",vbTextCompare) Then
If Not EnumIE.Exists(win.hwnd) Then
EnumIE.Add win.hwnd,win
End If
End If
Next
End Function
調用的時候,我采用了遞歸調用,只要有子窗口沒有關完,就會繼續關。這里用do while的話會多執行一次EnumIE這個函數,大家可以考慮換一種循環方式,我就不多說了。
Set allIE = EnumIE()
Do while allIE.Count>0
For each oIE in allIE.Items
oIE.quit
Next
Set allIE = EnumIE()
Loop
當然了QTP有自己的方法會很快關閉所有的IE窗口:
SystemUtil.CloseProcessByName(“iexplore.exe”)
下面介紹下利用DOM操作測試對象的幾種常用方法,還是用百度主頁做例子,首先將百度主頁加進對象庫。
IE8里會自帶F12開發工具,可以方便你看你需要的DOM屬性
Set oDOM = Browser("百度一下,你就知道").Page("百度一下,你就知道").Object
需要注意的是,此處的Object屬性目前只支持IE,而對其他的瀏覽器目前還沒有加入支持。
1. 通過getElementById方法獲取定位對象,對其進行操作:
oDOM.getElementById("kw").value = "態度決定測試"
oDOM.getElementById("su").click
2. 通過getElementsByName方法獲取定位對象,對其進行操作:
方法一:
Set oEdits = oDOM.getElementsByName("wd")
For each oEdit in oEdits
oEdit.value = "態度決定測試"
Next
oDOM.getElementById("su").click
方法二:
Set oEdits = oDOM.getElementsByName("wd")
oEdits(0).value = "態度決定測試"
oDOM.getElementById("su").click
通過方法名里Element后面的復數形式也大概可以知道這個方法返回的是一個集合,所以需要遍歷集合里的對象獲取這個對象。
3. 通過getElementsByTagName方法獲取定位對象,對其進行操作:
Set oEdits = oDOM.getElementsByTagName("INPUT")
For each oEdit in oEdits
If oEdit.type = "text" Then
oEdit.value = "態度決定測試"
End If
Next
oDOM.getElementById("su").click
用這個方法遍歷之后通常要加判斷,因為一個頁面里可能有很多INPUT標簽。
4. 利用FORM來獲取對象元素,對其進行操作:
oDOM.f.wd.value = "態度決定測試"
oDOM.f.su.click
5. 訪問頁面里的Script腳本變量
通過DOM可以直接訪問到頁面中的JS或者VBS中的變量,還是以百度為例,我們用F12進行探測,可以看到k這個變量: k = d.f.wd
oDOM.parentWindow.k.value = "態度決定測試"
oDOM.getElementById("su").click
從代碼里可以看出,我們只需要通過parentWindow去訪問web頁面中的變量即可。
下面我們來說說利用DOM完成QTP無法完成的任務:
還是百度,假設我們需要驗證一些屬性,此時我們可以使用CurrentStyle來驗證。
Set oDOM = Browser("百度一下,你就知道").Page("百度一下,你就知道").Object
Set p = oDOM.f.CurrentStyle
msgbox p.color
我們可以驗證表單的顏色。
利用DOM還可以提升我們的腳本性能,舉個例子,自己構建一個含有100個文本框的HTML頁面,每個文本框的name屬性都是由text_開頭,之后由1到100遞增。首先將Page對象加到對象庫里去。
效果圖如下:
接下來我們就可以引入保留對象Services的Transaction屬性來驗證性能是否有提高。
QTP描述性編程:
Services.StartTransaction "test"
For i =1 to 100
Browser("Browser").Page("Page").webEdit("name:=text_"+cstr(i)).Set "hello world"
Next
Services.EndTransaction "test"
運行后結果大概用了11.5秒時間填寫完一百個webEdit對象。
DOM操作腳本:
Set oDOM= Browser("Browser").Page("Page").Object
Services.StartTransaction "test"
For i =1 to 100
oDOM.getElementsByName("text_"+cstr(i))(0).value = "hello world"
Next
Services.EndTransaction "test"
結果只用了1.8秒時間,效率驚人。
如果文本框更多的話,那么DOM操作對象的優勢將進一步顯現出來。這對性能的提升會有巨大的幫助。
posted on 2014-10-30 11:09 順其自然EVO 閱讀(454) 評論(0) 編輯 收藏 所屬分類: 測試學習專欄 、selenium and watir webdrivers 自動化測試學習