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操作對象的優勢將進一步顯現出來。這對性能的提升會有巨大的幫助。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM