[softwaretest_cesoo_ww] Re: [softwaretest_cesoo_ww] Re: [softwaretest_cesoo_ww] Re: [softwaretest_cesoo_ww] 关于脚本中QTP的未知的错误

  • From: Liu <liushining@xxxxxxxxx>
  • To: softwaretest_cesoo_ww@xxxxxxxxxxxxx
  • Date: Wed, 3 Feb 2010 17:16:33 +0800

的确如此,这个问题很好,揭示了qtp有一个深层的局限。就是页面在reload之后,QTP再指向的DOM就已经失效了。
网上有一篇英文文章《QTP mysterious Init
method》曾经专门说过这个问题。sorry,我昨晚没注意到你这个childobject是在循环之外,让你浪费时间了。呵呵。
全文如下,可细读一下:
QTP mysterious Init method

*One limitation of QTP that has always bothered me is the inability to reuse
its web objects after the browser reloads. I spend countless cpu cycles
parsing the DOM to find an element, grab enough properties to make it
unique, build a description with those properties and finally get the right
micobject. Then I perform some action and that reloads the page, and my
object is useless. If I want to use it, I have to start the process all over
again.*

*After years of struggle to find an answer, I packed some gear, hired a
Sherpa and set off to find a guru who could give me an answer.*

*The dialog went something like this.*

*Me: Great guru, I must know how to reuse an object after a page refresh.
Guru: Look to the object. Your answer is in it.
Me: eh?
Guru: The object; your answer is in it.
Me: That doesn't even make sense.
Guru: Go now. By the time you reach home, you will have solved the mystery.
Me: But I'm not good at riddles.
Guru: It was a play on words, but since you are too dense to understand I'll
just come out and tell you. QTP's web objects have an undocumented method
called .init. Use it to reinitialize an object ofter a page load.
Me: Oh, now I get it "in it" and "init". That's pretty clever.
Guru: Be warned, this is not a supported feature and must not be spoken of
in the presence of HP support.
Me: gotcha.*

*My point here is that it turns out QTP has an undocumented method called
init in all its web objects. When you call WebElement.init, QTP will find
the object on the page again...even after the page has reloaded.*

*For example, this code passes as-it, but if you comment out the penultimate
line, you will get an error on the last line.*
*View as plain 
text*<http://www.softwareinquisition.com/2008/05/qtps-mysterious-init-method#>
*Visual Basic: *

   1. *Set oBrowser = Browser("version:=inter.*")*
   2. *oBrowser.navigate "http://www.google.com"*
   3. *Set oWebEdit = oBrowser.WebEdit("name:=q", "index:=0")*
   4. *oWebEdit.Set "software inquisition"*
   5. *oWebEdit.submit*
   6. *oBrowser.sync*
   7. *oWebEdit.init*
   8. *oWebEdit.Set "wally llama"*

**

*I have been warned that this is not supported by HP, so if it doesn't work
for you, don't call them.*



在 2010年2月3日 下午4:27,gao fei <lumieregf@xxxxxxxxx>写道:

> 更改了脚本,目前运行正常了。
> 下面是原脚本和修改后的脚本。
>
> ---------------------------------------------------
> 脚本功能:
> 使用ChildObjects方法,取知识来源list中所有webtable。当查询到case之外的脏数据时执行删除操作。
>
>
> 下面是昨天的脚本,在加上msgbox KoCount(i).toString时的提示信息。
>
> Set KoCount = Browser("ForceView Service Desk").Page("| ForceView Service
> Desk").ChildObjects(w_table)
> NoOfChildObjs = KoCount.Count()
>
> msgbox NoOfChildObjs
> ' - - - 取出知识来源列表中的所有数据- - - - -
> Do while i < NoOfChildObjs
>  msgbox i
>  Dim MyVar,MyProperty
>
> ' 当删除一条数据后,运行到下面 msgbox KoCount(i).toString这句时报错。
> ' msgbox的提示是 [WebTable ] table
>  msgbox KoCount(i).toString
>
>  Set checkClick = KoCount(i).childItem(1,1,"WebElement",0)
>  Set tableObject_Name = KoCount(i).childItem(1,2,"WebElement",0)
> '取出知识来源的名称
>  knowladgeValue =  tableObject_Name.GetROProperty("innertext")
>
> ' 下面是Do循环语句和昨天的脚本一样。
>  Do
>        ...
>
>    Loop
>
> --------------------------------------------------
>
> 今天修改后的脚本:
>
>  Dim NoOfChildObjs,RowCount,runRowValue,i,knowladgeValue
> Dim numOfChildObjs,numChangeTable
> i = 0
>
> Set w_table = Description.Create()
> w_table("html tag").value = "TABLE"
> w_table("class").value = "x-grid3-row-table"
>
> Set KoCount = Browser("ForceView Service Desk").Page("| ForceView Service
> Desk").ChildObjects(w_table)
> NoOfChildObjs = KoCount.Count()
>
> ' 开始进入循环删除数据
> Do while i < NoOfChildObjs
>  Dim MyVar,MyProperty
>
> ' 在循环里面使用ChildObjects,再取一次list中的webTable后就正常运行了
>  Set chObject = Browser("ForceView Service Desk").Page("| ForceView
> Service Desk").ChildObjects(w_table)
>  Set checkClick = chObject(i).childItem(1,1,"WebElement",0)
>  Set tableObject_Name = chObject(i).childItem(1,2,"WebElement",0)
>
>  knowladgeValue =  tableObject_Name.GetROProperty("innertext")
>
>   '将知识列表中的数据与不能删除的数据一一比较
>  Do
>   Select Case knowladgeValue
>    Case "服务请求"
>     i = i+1
>     Exit Do
>    Case "事件流程"
>     i = i+1
>     Exit Do
>    Case "问题流程"
>     i = i+1
>     Exit Do
>    Case "变更流程"
>     i = i+1
>     Exit Do
>    Case "发布流程"
>     i = i+1
>     Exit Do
>    Case "网络流程"
>     i = i+1
>     Exit Do
>    Case "任务流程"
>     i = i+1
>     Exit Do
>    Case Else
>
>     checkClick.FireEvent("onclick")
>
>     Browser("ForceView Service Desk").Page("| ForceView Service
> Desk").WebButton("删除选中项").Click
>     Browser("ForceView Service Desk").Page("| ForceView Service
> Desk").WebButton("是").Click
>     Exit do
>   End Select
>
>  loop
>
>     Set chObject2 = Browser("ForceView Service Desk").Page("| ForceView
> Service Desk").ChildObjects(w_table)
>
>     numChangeTable = chObject2.Count()
>
>     If numChangeTable = 6 Then
>    Exit Do
>   End If
> Loop
>
> ---------------------------------------------------
>
> 说明:
>  橙色里面是加入的语句。
>
> 结论:
> 是不是当删除了列表中的数据后,由于ChildObjects的子对象发生了变化,所以再用删除之前取的对象集合中的数据就不在正确了。必须保证每次对象集合中的对象和最新的、更新过的数据一致。
>  所以在循环中运用取对象集合的ChildObjects方法,才是正确的。
>  我觉得应该是这个原因造成的昨天的错误吧?老师您觉得问题是出在这里吗?
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> 2010/2/2 Liu <liushining@xxxxxxxxx>
>
>  表扬一下,问题描写得很详细,环境,目标,出错条件和信息,有一个优秀的软件测试人员的潜质。
>> 从截图上看,web页面截图上有10个流程,而在debug截图中,NoOfChildObjs为8个。是不是页面里还包含其他table对象。
>> 1. 建议spy一下整个页面,看看你的table description是否和实际页面上的每个对象都能匹配
>> 2. 另外,在调用childitem之前,可以先调用KoCount(i).toString,查看一下当前对象是否真的是你想要的。
>> 先这样试试吧。有了结果告诉我。
>>
>> 在 2010年2月2日 下午4:47,gao fei <lumieregf@xxxxxxxxx>写道:
>>
>>  老师,您有空帮我看看下面的问题吧。我抽时间写了个脚本,但是有个问题,原因我没查出,您帮我看看问题在哪儿呢?
>>>
>>> -----------------------------------------------------------------------
>>> 脚本功能:
>>> 将知识来源列表中除“服务请求、事件流程、问题流程、变更流程、发布流程、任务流程”以外的数据删除。
>>>
>>> 脚本如下:
>>>
>>> '这个脚本主要任务是将知识来源列表中的所有数据选中,并且删除多余的脏数据。
>>> Browser("ForceView Service Desk").Page("ForceView Service
>>> Desk").WebElement("WebElement").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("ForceView Service
>>> Desk").WebEdit("user.password").SetSecure "4b67b9e87941c663b844160326e4885c"
>>> Browser("ForceView Service Desk").Page("ForceView Service
>>> Desk").WebButton("login").Click
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebElement("WebElement").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebElement("WebElement_2").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebElement("管理").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebElement("WebElement").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebElement("WebElement_2").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebElement("WebElement_3").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebElement("管理").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebElement("WebElement_4").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebElement("配置设置").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").Link("配置设置").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").Link("知识库设置").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").Link("知识库设置").Click
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebElement("WebElement_4").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebElement("WebElement_5").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebElement("知识状态").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").Link("知识来源").FireEvent "onmouseover"
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").Link("知识来源").Click
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebElement("WebElement_6").FireEvent "onmouseover"
>>>
>>> Dim NoOfChildObjs,RowCount,runRowValue,i,knowladgeValue
>>> i = 0
>>>
>>> Set w_table = Description.Create()
>>> w_table("html tag").value = "TABLE"
>>> w_table("class").value = "x-grid3-row-table"
>>>
>>> Set KoCount = Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").ChildObjects(w_table)
>>> NoOfChildObjs = KoCount.Count()
>>>
>>> msgbox NoOfChildObjs
>>>
>>> ' - - - 取出知识来源列表中的所有数据- - - - -
>>> Do while i < NoOfChildObjs
>>>  msgbox i
>>>  Dim MyVar,MyProperty
>>>
>>>  Set checkClick = KoCount(i).childItem(1,1,"WebElement",0)
>>>  Set tableObject_Name = KoCount(i).childItem(1,2,"WebElement",0)
>>> '取出知识来源的名称
>>>  knowladgeValue =  tableObject_Name.GetROProperty("innertext")
>>>
>>>  ' 将知识列表中的数据与不能删除的数据一一比较
>>>  Do
>>>   Select Case knowladgeValue
>>>    Case "服务请求"
>>>     'msgbox "1"
>>>     Exit Do
>>>    Case "事件流程"
>>>     'msgbox "2"
>>>     Exit Do
>>>    Case "问题流程"
>>>     'msgbox "3"
>>>     Exit Do
>>>    Case "变更流程"
>>>     'msgbox "4"
>>>     Exit Do
>>>    Case "发布流程"
>>>     'msgbox "5"
>>>     Exit Do
>>>    Case "网络流程"
>>>     'msgbox "6"
>>>     Exit Do
>>>    Case "任务流程"
>>>     'msgbox "7"
>>>     Exit Do
>>>    Case Else
>>>     checkClick.FireEvent("onclick")
>>>     wait 1
>>>     Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebButton("删除选中项").Click
>>>     wait 1
>>>     Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebButton("是").Click
>>>     wait 1
>>>     Exit do
>>>   End Select
>>>  loop
>>>
>>>  msgbox i
>>>  i = i+1
>>>  msgbox i
>>> Loop
>>>
>>> Browser("ForceView Service Desk").Page("| ForceView Service
>>> Desk").WebButton("退出").Click
>>>
>>>
>>> 症状说明:
>>> 第一次删除与保留数据无关的数据时,可正常删除。但是循环后,第二次删除时,在Set checkClick =
>>> KoCount(i).childItem(1,1,"WebElement",0)处保错。
>>>
>>> Test Result提示:
>>> General run error.
>>> Line(45):"Set checkClick = KoCount(i).childItem(1,1,"WebElement",0)"
>>>
>>> 在报错时点了『Debug』按钮,查看 Variables 页面中的变量(debug viewer的图、产品界面图均在附件中)。
>>> 在 Command 页面中执行了一下 MsgBox Err.Number,提示-2147467259
>>> 再执行 MsgBox DescribeResult(Err.Number),弹出对话框显示“未知错误”。
>>>
>>>
>>> -----------------------------------------------------------------------
>>>
>>> 是循环语句造成的错误吗?问题可能出在哪里呢?
>>>
>>>
>>>
>>>
>>
>>
>

Other related posts:

  • » [softwaretest_cesoo_ww] Re: [softwaretest_cesoo_ww] Re: [softwaretest_cesoo_ww] Re: [softwaretest_cesoo_ww] 关于脚本中QTP的未知的错误 - Liu