看到很多人被QTP弄得暈頭轉向,我深有感觸,有一句話突然浮上心頭“不識廬山真面目,只緣身在此山中”。當你接觸並研究過多個工具之後,會發現道理原來就是這麼簡單。這裏也送迷路者一句話:工具永遠只是工具,工具永遠是被利用的,你更需要把握問題的本質。
廢話不多說了,當年我用的版本是QTP9.0,這裏把我對QTP的一些認識重新整理,和各位分享,仁者見仁,智者見着,大家相互學習,共同切磋。有什麼不正確的地方,歡迎大家指出。整理的思路我按照從淺入深逐步展開,以便大家理解。例子就以Web應用爲例,這個我比較熟悉,但道理是共通的。當然要了解本文,你還是需要具備基本的QTP知識,至少要知道錄製、回放、對象庫、描述性編程等基本概念。
QTP對象庫
例如我們以Google的搜索爲例錄製腳本,代碼如下:
Browser("Google").Page("Google").WebEdit("q").Set "qtp"
Browser("Google").Page("Google").WebEdit("q").Submit
當錄製下這段代碼之後,QTP做了哪些事情呢?
1.首先最明顯的在QTP主窗口的專家視圖下多了兩行代碼(廢話-_-!)
2.其次我們打開Object Repository,發現QTP創建了一些對象
QTP自動生成的代碼怎麼理解?結合Object Repository,可以這樣理解,有一個名叫Google的根節點Browser對象,這個對象中有一個名叫Google的Page對象,Page對象中有名叫q的WebEdit對象,WebEdit對象執行了Submit方法。實際上Browser()這是Browser對象的默認方法,這個方法接收一個對象名參數,返回Browser對象,Page和WebEdit也類似。除了用對象名參數化對象方法之外,還可以用其他的屬性或者對象參數化。
這段代碼涉及3種類型的對象:Browser對象、Page對象、WebEdit對象。怎麼知道這些對象的類型,可以在Object Repository窗口的右側的Class屬性就知道了。右側的有部分屬性是不能修改的,有部分屬性是可以修改。可修改的屬性都有一個默認顯示的列表,點擊添加按鈕可以改變默認值的設置。這個有什麼作用呢?默認的屬性是QTP用來描述抓取下來的對象的,你可以通過修改它讓QTP在執行時根據你的設置靈活的匹配實際的對象。
本文出自asoqa的51Testing軟件測試博客:http://www.51testing.com/?233320
QTP怎麼去標識一個對象?
在錄製時,QTP根據Object Identification中定義的對象屬性在錄製時識別頁面的元素,並映射成QTP的測試對象(Test Object, TO);同時根據Web Event Configuration中定義的規則識別對象事件。默認QTP自帶了對ActiveX、Visual Basic、Web對象的識別規則,其他例如Java、Flash等的需要加載相應插件。
在回放時,QTP根據測試對象的屬性定位實際頁面上的對象(Run-time Object, RO),並在RO上執行事件。如果回放時找不到對象,QTP會默認啓動智能識別(Smart Identification),智能識別的規則在Object Identification中單獨定義。
More About錄製/回放
錄製的主要目的在於獲取對象,以便回放時能夠識別。獲取對象的方法有幾種方式,錄製只是其中一種,也就是錄製這一步不是必須的,可以跳過。那還有哪些方式可以獲取對象呢?
1. 用Object Repository的Add Object直接抓取對象,其實也是另一種形式的錄製
2. 常說的描述性編程,描述性編程又可以分成兩種基本類型:基於QTP Test Object的描述性編程和基於DOM Object的描述性編程。後者需要對對象識別的理解更加深入,這裏稍後介紹。而前者就是大家十分熟悉也經常使用的,具體有三種不同的使用方式:
a) Descrīption和ChildObjects組合
Set ōDesc = Descrīption.Create()
oDesc("micclass").Value = "WebRadioGroup"
Set ōbjs = Browser("Google").Page("Google").ChildObjects(oDesc)
objs(0).Select "#1"
b) 用Descrīption對象參數化Test Object
Set ōDesc = Descrīption.Create()
oDesc("name").Value = " 手氣不錯"
Browser("Google").Page("Google").WebTable("高級搜索").WebButton(oDesc).Click
c) 用屬性參數化Test Object
Browser("Google").Page("Google").WebTable("高級搜索").WebButton("name:=手氣不錯").Click
默認的,錄製回放時的事件都是QTP封裝後的事件。
定製對象事件
大部分情況下,我們使用QTP封裝後的事件就可以了。但是在某些情況下,我們需要在QTP對象上執行一些特殊的操作,這時我們希望能夠有某種手段能夠定製對象事件,QTP的RegisterUserFunc爲我們提供了這種功能。
1.註冊新方法
Function SetDefaultValue(test_object, ByVal val)
If StrComp(val, "") = 0 Then
test_object.Set "default"
Else
test_object.Set val
End If
End Function
RegisterUserFunc "WebEdit", "SetDefaultValue", "SetDefaultValue", TRUE
Browser("Google").Page("Google").WebEdit("q").SetDefaultValue ""
Browser("Google").Page("Google").WebEdit("q").Submit
上面這段代碼在WebEdit對象註冊了一個新的方法SetDefaultValue
2. 修改老方法
Function SetDefaultValue(test_object, ByVal val)
If StrComp(val, "") = 0 Then
test_object.Set "default"
Else
test_object.Set val
End If
End Function
RegisterUserFunc "WebEdit", "Set", "SetDefaultValue", TRUE
Browser("Google").Page("Google").WebEdit("q").Set ""
Browser("Google").Page("Google").WebEdit("q").Submit
這段代碼定義了SetDefaultValue方法並替換了以前的Set方法。
如何訪問DOM對象和方法(描述性編程)
前文提到描述性編程時有QTP Object和Dom Object之說,這兩個到底有什麼區別呢?所謂QTP Object包括TO和RO都是被QTP封裝後的對象,而DOM Object和QTP沒有什麼關係。我們知道Html是一種結構化的語言,而Html Dom定義了訪問和操作HTML文檔的標準方法,DOM Object指的通過DOM接口訪問的HTML文檔對象。那QTP如何獲取DOM Object?很簡單,只要通過Object屬性就可以使用DOM接口訪問這些對象。例如下面這段話就是通過DOM接口訪問Input對象,並直接將輸入框的value值賦值爲abc,相當於QTP WebEdit對象的Set方法:
Browser("Google").Page("Google").WebEdit("q").Object.value = "abc"
那什麼時候會用到DOM Object?怎麼用呢?
用QTP時,大家會發現有不少的對象QTP經常抓取不下來。例如某個Html代碼中DIV中套用了DIV:
<div id=”parentDIV” class=”class 1”>
<div id=”childDIV” class=”class2”>
<input id="inputid" class="textfield" type="text" value=””/>
</div>
</div>
大家可以試試,如果用QTP本身的對象抓取功能,如果想把兩個DIV層都抓取下來非常困難,如果對象都抓取不了,就更不要提後續的操作了。但如果用DOM接口去操作就會靈活的多,DOM將HTML結構視爲一棵樹,每個HTML文檔元素及其屬性是樹上一個節點,可以用getElementById直接訪問它們,也可以通過childNodes屬性一層一層的訪問。下面是一段範例代碼:
'獲取childDIV對象
Set ōbj = Browser("Browser").Object.document.getElementByIdx_x_x("childDIV")
'獲取childDIV的子節點
Set co = obj.childNodes
'childDIV的子節點爲input對象
Set inputObj = co(0)
'設置input文本框的內容爲aa
co(0).value = "aa"
當然這些通過QTP Object的描述性編程也是可以做到的。關於Html Dom的詳細介紹可以到這個網址看看:http://www.w3school.com.cn/htmldom/index.asp
More About 描述性編程
Object屬性通過DOM提供了一種直接訪問Web元素屬性的途徑。除此之外QTP還支持一種直接訪問Web元素屬性的方式,就是attribute/[屬性]的方式。
例如有一段源代碼如下:
<A href="http://www.google.cn" lid="l1" id="link1">link1</A>
<A href="http://www.baidu.com" lid="l2" id="link2">link2</A>
QTP腳本可以這樣寫
'點擊link1的鏈接
Browser("Browser").Page("Page").Link("attribute/lid:=l1").Click的方式點擊link1的鏈接。
'打印link1的lid的屬性值
Msgbox Browser("Browser").Page("Page").GetRoProperty("attribute/lid:=l1")
好,現在我們知道了一種更加靈活的方式操作Web對象。但畢竟很多HTML元素頁面上是看不出效果的,那我們怎麼知道Web對象的結構,以便獲取他們並進行操作呢?最土的辦法就是查看源代碼,但是源代碼往往夾雜着大量的動態代碼和註釋,看起來挺累。這時可以藉助一些工具。這裏我推薦ie developer toolbar,這個是微軟出的ie插件,可以查看每個html文檔元素的結構及屬性,包括css樣式,操作簡潔,功能完全可以彌補QTP對象識別的不足。如下圖:
不過有點遺憾的是,QTP對於Object屬性有這樣一個說明“TheObjectproperty for Web objects is supported only when running steps on Internet Explorer. It is not supported when working with Netscape Browser or Mozilla Firefox”,看來QTP只支持IE對於DOM Object的訪問。