扼杀QTP检查点

上一篇 / 下一篇  2009-09-06 15:59:47

【扼杀QTP检查点 2】

 

 

首先,简单说下,什么是检查点。因为检查点在测试领域中涉及面较广,所以我们这里主要针对QTP的检查点做个概念性的介绍,它是QTP在运行过程中,对被测试对象的属性、输入、输出值做的一个检查,如果发现预期结果与实际结果不同,便会以报告的方式显示出来给用户或者返回值。51Testing软件测试网D:j+JD!\ B0o9tj

  其次,知己知彼,方能百战不殆。让我们了解下,QTP检查点的基本工作原理,QTP把某个对象添加到一个“库”中,并记录了它的属性,值等,在运行的时候,把用户指定的属性,值与运行过程中(类似getroproperty)的属性与值进行比较。直到V9.5出台,检查点管理才上升到界面上,并归并于对象库中。至此,检查点的原理在9.5的粉饰下更让人容易接受和入门。51Testing软件测试网S'^$eb%|q%C-}^*M

  再次,为什么要添加检查点?因为使用QTP,无论是回归测试,或者其它方面的测试,我们需要一个检查点,一个触发点来达到捕获BUG或者触发事件的目的。因此,渐渐的很多刚用QTP的人便把检查点看成一个能够解决自动化瓶颈的一个出路。所以在一个简单的脚本中,检查点是一个接一个的插进去,琳琅满目。51Testing软件测试网5x{1uIX9Z t(~7X&L

  最后,关于检查点的用法,可以在网上搜索下关于这方面的资料,它包括了表、对象、数据库、位图、文本、页面、输入输出值等等。

6Nc&?A;ZY5@M#a273596

  在这里介绍个简单的Link检查点的玩转方法,自然不是挑战XEnu之类的工具,在这里之所以介绍这个方法,是想让更多的读者学会思考,教材是死的,人才是活的。51Testing软件测试网)WP:smrZ`8g

  1,设置一个URL让它去跑,我们选择了Google,然后随便做个操作,例如做个set操作。没办法,添加检查点就是要这么麻烦。51Testing软件测试网DM~.Z"D"I2V e

  2,第1步其实是让谷歌首页的页面截图有出现到我们的Screen中。好了,点击停止。然后在Screen上邮件添加"Images"为标准检查点。51Testing软件测试网 F-{N:M5O6o

      Browser("Google").Page("Google").Link("Images").Check CheckPoint("Images")51Testing软件测试网M}R9l_7gA

  3,我们只选择了html tagURL(不要outerhtml之类的),让html taga(连接其实有很多中节点方式,需要根据实际去做参数化),URL用正则表达式参数化成"http://(.*)"

9d7i0cg"pi6A3dP-X&N HN273596

  4,然后到对象库中,把刚才的Link("Images")text做个参数化,例如添加个环境变量EnvironmentImages_text”。51Testing软件测试网1Q$v5|(s'z8XO O"l!}qZ

  5,关于这个对象库中的,我们不要添加太多的属性进去,特别是URL不要加进去,我们就是要通过URL来做检查的(为什么不把对象库中的URL同样也做这种表达的参数化?这点留给细心的读者去思考)

URa'K P8]6vfm:A273596

  6,运行下面代码:

;P3l l$@'P273596

-1   Dim LinkObj

-2   Set LinkObj=browser("Google").Page("Google").Object.links   

-3   For i=0 to LinkObj.length-1

-4        Environment.Value("Images_text")=LinkObj(i).outertext

-5   Browser("Google").Page("Google").Link("Images").Check CheckPoint("Images") 

-6   Next

   7,第5行就是我们自己添加的检查点,区别8.29.5,前者使用的复制黏贴Screen不会跟踪,直到9.X才改善了这个问题。

   8,大家很高兴的在Report中看到了若干个检查点的成功报告,而报告的内容就是HTMLURL的检查。至于它的实用性,抛砖引玉。

 

   好了,检查点我们也大概知道个二三,现在我们来说说,这么好的一个检查点,为什么要扼杀它,或者说是对许多QTP用户一个新触发点。

1,在比较稳定的版本QTP8.2中,检查点的添加,保存都是以这一个文件的形式,并未体出一个可维护性高的特点。

2,对象变更,检查点毛病会体现出来,需要重新添加一次检查点或者像在9.5中需要修改属性,因为它的原理基于对象库。

3,项目保存或者移植(被测项目修改)screen丢失或者错乱,会让检查点添加是个让人头痛的问题,因为你需要整理screen或者重新添加,更甚是在8.2中不支持检查点图片跟踪,导致了复制同样的检查点,没办法做到维护。

4,某些检查点的添加是基于screen,当screen出现了第3点中的情况后,项目的维护成为QTP脚本管理员的一个隐痛,自然,琳琅满目的检查点更是让情况发生恶化。

5,检查点的原理基于对象库,因此,对象库中的毛病也会体现出现,维护,移植,管理...

6,框架的可拓展性,因为检查点的特点,导致了它的添加必须基于录制,过渡依赖于Action的使用。会让检查点的添加不能在单独的Function

中使用而。

7,功能局限性,检查点虽然提供了哪么多类型的检查点,但实际上它能做到的或者是读者想要的,远远不只这些东西。

  那么,不用检查点,我们有更好的方法去解决吗?我们用检查点干什么?就是为了发现包括回归过程,测试过程中找到与预期结果不同的页面元素。考虑到重用性、可维护性、框架拓展性,我们采用了Function的编写。这并不是舍简求繁,路需要走得更远,这是一个积累的过程。在这里简单举12个例子。

'WebEdit_CheckPoint输入框检查点函数,输入参数为预期值'WebEdit_Obj      输入框对象

'CanVisible       

'CanEdit   可编辑



'MaxLength        最大长度 

Public function WebEdit_CheckPoint(WebEdit_Obj,CanVisible,CanEdit,MaxLength)

             If WebEdit_Obj.getroproperty("visible")<>CanVisible then

                    Reporter.ReportEvent micWarning, "WebEdit visible is not expect "&CanVisible, "WebEdit visible is not expect "&CanVisible

        

 

        If WebEdit_Obj.getroproperty("readonly")=CanEdit then

                    Reporter.ReportEvent micWarning, "WebEdit CanEdit is not expect "&CanEdit, "WebEdit CanEdit is not expect "&CanEdit

             

 

             If WebEdit_Obj.getroproperty("max length")<>MaxLength then

                    Reporter.ReportEvent micWarning, "WebEdit MaxLength is not expect "&MaxLength, "WebEdit visible is not expect "&MaxLength

             end if

   End Function

      

WebEdit_CheckPoint browser("Google").Page("Google").WebEdit("q"),false,false,100 

'IMG_CheckPoint输入框检查点函数,输入参数为预期值

'参数

'IMG_Obj               输入框对象

'CanVisible           可见

'Filename               文件路径

'URL                    超连接地址51Testing软件测试网Q6J%U!Z'{Vjt

'LoadOver             加载完毕

Public function IMG_CheckPoint (IMG_Obj,CanVisible,Filename,URL,LoadOver)      If IMG_Obj.getroproperty("Visible")<>CanVisible Then

              Reporter.ReportEvent micWarning, "Image visible is not expect "&CanVisible, "Image visible is not expect "&CanVisible

      End If

 

      If IMG_Obj.getroproperty("src")<>Filename Then

              Reporter.ReportEvent micWarning, "Image src is not expect "&Filename, "Image src is not expect "&Filename

      End If

:V [ }U,Q[[:t273596

 

      If IMG_Obj.getroproperty("URL")<>URL Then

              Reporter.ReportEvent micWarning, "Image URL is not expect "&URL, "Image URL is not expect "&URL

      End If

 

      If IMG_Obj.object.readyState<>LoadOver Then

              Reporter.ReportEvent micWarning, "Image LoadOver is not expect "&LoadOver, "Image LoadOver is not expect "&LoadOver

      End If

End Function

 

IMG_CheckPoint browser("Google").Page("Google").Image("Google"),True,"http://www.google.com/intl/en_ALL/images/logo.gif","","complete"

 

以上2个方法,都是可以根据实际情况再做修改和完善的。  自然,这些都是检查点可以做到的,我们也做到了,但是,什么是检查点做不到的呢?因为它的名字叫“检查点”,是点就自然有它覆盖不到的地方!大家在做网页测试的时候,是否发现有些地方会出现类似Http错误之类的提示,或者页面出现某些错误但QTP却无动于衷?更甚至是出现在Frame内部,让人难以捉摸。所以到了项目提交,感觉可以了,但给用户使用时候,却发现某个页面里面,页面出现了某些页面报错或者加载出错,从而动摇了自动化回归的价值,在下一篇中将介绍如何把点扩张到线乃至面
    在做自动化脚本录制与回放过程中,只有当用户针对某个功能做的检查点,QTP才会把这个对象的预期结果做判断,给着人一种“各扫门庭雪”的感觉。或者有些地方会出现类似Http 错误之类的提示,或者页面出现某些错误但QTP却无动于衷,因为你没有对这些做监测点的设置。但这么多的对象做监测点设置是件很麻烦的事情,而你不做,却又会对项目在做验收时候看不到多大的效果。为此我们结合了上节我们的方法,就是自己编写简单的函数对这个页面做判断。
    哪么,一个web页面出现错误的情况大概都有那些?读者可以自己在脑海中想想在自己的测试工作过程中,都发现了那些类型的页面错误?结合到这点简单的提到一下几点:
标题提示错误。这个应该是给用户最直观的。“找不到页面”、“HTTP 错误”、“找不到服务器”等等;如图-01:


图(01)


2,URL错误。它涉及到的,可以是当前页面的URL错误,或者是Frame内部的URL错误。错误的标准可以是公司内部自己提供的错误后跳转的URL,只要出现这个URL跳转出来的页面,哪么它也是错误的;如图-0251Testing软件测试网6S#Ocw)z-fw




图(02)


页面输出错误。这点是比较泛的,区别于第2点就是某些错误的页面它是不会跳转到我们指定的URL,导致了显示出错。如图-03


-


图 (03)


4,WinStatusBar 的错误提示。这一点在测试的过程中,很多的测试人员或者开发人员对这个很不敏感,有些错误不易见的错误我们是可以在这个WinStatusBar中看出来的。如图-0451Testing软件测试网0@(H%}7Thv




就先说这4点,在看到这4点后,读者可以先试试如何把这4点写成函数。首先,针对这个错误的比较,我们的前提是错误类型字眼的出现,为此我们先编写一个判断正则表达式的函数。
 RegExpbld 正则表达式的判断


' patrn               正则表达式
' strng               字符串''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''Public Function RegExpbld(patrn, strng)
regEx, retVal                      ' 建立变量。
Set regEx = New RegExp         ' 建立正则表达式。
regEx.Pattern = patrn             ' 设置模式。
 regEx.IgnoreCase = true          ' 设置是否区分大小写。          retVal = regEx.Test(strng)         ' 执行搜索测试。       
RegExpbld=retVal
End Function

其次,第1,2,4点的函数编写实现难度不高。好比第1点中,我们只需要取出 Browser的标题,并使用上面的表达式函数便可以
-1 RegExp = "错误|error|无法"    ‘这个是我们简单编写的正则表达式-2 title=browser("Google").getroproperty(“title”)51Testing软件测试网SI\T&|%QU
-3 if RegExpbld(RegExp, title) then
-4   '如果出现这些错误的字样则报错
 end if
但在第2点中,需要提醒大家的是,捕获这个错误的URL,不仅仅是当前页面的URL,我们还需要取出在页面中所有frame的URL做对比。
' 参数
      公司内部自定义的错误页面跳转URL,可以写成数组之类去进行比较
-1        Dim FramesObj
    Set FramesObj =browser("Google").Page("Google").Object.frames   
     For i=0 to FramesObj.length-1
-4            If FramesObj (i).getroproperty("url")= error_url        Then
-5                         '如果为true就是某个frame已经跳转到指定的URL
              End If
    Next
:
再次,我们针对第三点,我们查错的标准是当前页面中是否出现了类似第1点中的错误字样:"错误|error|无法"。但是如何实现呢,在这里简单介绍3个方法。
第一:通过QTP自带的TextUtil对象去做页面字体捕获。软件测试网r J@8uUG7RW1oT8\
' QTP_DocIsLive 通过TextUtil 对象判断页面是否存在某个特定错误字样




Public Function QTP_DocIsLive()
Dim Src_text,patrn
Src_text=TextUtil.GetText(0, 20, 20, 2000, 2000)   '窗口的大小需要根据实际去定义
patrn="错误|error|无法
If RegExpbld(patrn,Src_text) Then
QTP_DocIsLive=true
     Exit Function
End If
QTP_DocIsLive=false       
End Function
  
 优势:原理简单,甚至能查找到不可预知的msgbox中的内容。
  弊端:QTP本身对这个TextUtil的支持并不是做得很完善,导致了方法是使用过程中,偶尔会与Window Explorer 冲突,导致了使用函数完后,Window会出现某些异常情况。  \
第二:通过浏览器自带的查找功能。
' New_Page_Docfind 通过IE 自带查找功能判断页面是否存在某个特定错误字样
'参数
 New_Page_Doc    用户自己输入的查找字样,不支持正则表达式,需要自己编写循环查找
Public function New_Page_Docfind(New_Page_Doc)
 Dim oShell
        SetShell=CreateObject("WSCript.shell")
        oShell.sendkeys  "^f"        '发送”Ctrl+F”调出查找功能51Testing软件测试网WJ6es9yW
        browser("browser").Window("查找").Page("查找").WebEdit("WebEdit").Set New_Page_Doc        '设置搜索文本的内容,用户需要自己添加对象或者修改成描述语言51Testing软件测试网u&K'BNE"L4Ag!Or
        browser("browser").Window("查找").Page("查找").WebButton("查找下一个(F)").Click
1_9n O8E"b(_ U273596'点击查找按钮51Testing软件测试网y9hU-}7Ti;R
        If browser("browser").Window("查找").Dialog("Microsoft Internet Explorer").Exist  Then51Testing软件测试网ZI%F_w1s
            browser("browser").Window("查找").Dialog("Microsoft Internet Explorer").Close51Testing软件测试网 c.x5~a'l5q)s0a
                        wait(0.1)
:q]6}5HeVX273596                        oShell.sendkeys  "%u"
y6la2u a2xy273596                        browser("browser").Window("查找").Page("查找").WebButton("查找下一个(F)").Click51Testing软件测试网Sg!g5Hy:SA]
                        If browser("browser").Window("查找").Dialog("Microsoft Internet Explorer").Exist  Then
{#M!q}&I273596                                browser("browser").Window("查找").Dialog("Microsoft Internet Explorer").Close
hX^2dV*`*i,S c"zy273596                                New_Page_Docfind=false51Testing软件测试网x6it `'O4vCMl'Q
                                browser("browser").Window("查找").Close
u$z X4V,H273596                                else51Testing软件测试网 @qVj'sZ Xp^Lx:F
                                New_Page_Docfind=true51Testing软件测试网$lGl,Q&^ {#r
                                browser("browser").Window("查找").Close51Testing软件测试网dV;]g!y tJi
                        end if
\lW*ExkRF.}H273596     else
:z`GN[qS273596                        New_Page_Docfind=true51Testing软件测试网)s:m~:zt`
                        browser("browser").Window("查找").Close
/nZ)mkl Ej$I273596        End If51Testing软件测试网i+F OMTO
        Set Shell=Nothing51Testing软件测试网:`)~']"?fC
End Function51Testing软件测试网 c p+E(}Z/t;o!t4n#G6m
51Testing软件测试网(ec4qm(^i4P2x+e
优势:针对某个特定字眼查找速度快,准
)~#G4hB/{*`,R273596      
0P-\?!JM/[.R.k273596弊端:如果特定字眼多,会导致速度下降,界面闪动较为厉害
:}-Vt|.plb273596      函数中的某些对象是建立在对象库的基础上的,移植效果差强人意。
_s}LN@7J1{~273596      不能同时对多个Frames做查找,需要点击触发51Testing软件测试网)_X]8wT Jyp_f

#Mm\8SKtBL)?273596第三:使用DocumentElement 对象。51Testing软件测试网9b e$q ]*r6K_

9D-d-t.o4B4c4F]9zM273596'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''51Testing软件测试网/f+s(t/L `$ey
' New_Page_DocExist 使用DocumentElement 对象判断页面是否存在某个特定错误字样51Testing软件测试网XO_ DNU1T
'
]EmMF/gD1\-b273596'参数
3HwW0AGS5|jP273596' reg    正则表达式
8P)a I-U-@*f:v273596''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
^Q^"Xud4z){kn273596Public Function New_Page_DocExist(reg)
.SlH]SZ}273596Dim Page_doc_a,Page_doc_b,Page_doc_c,str,oDesc,frame_obj,logie,child_a51Testing软件测试网'}(uK u+RF Y-D
          str=browser("browser").GetROProperty("title")51Testing软件测试网jnq4V'`
          If browser("browser").page("index:=0").Exist Then
&@Y(No|8I273596                          Set Page_doc_a=browser("browser").page("index:=0").Object.documentElement.all.tags("body")51Testing软件测试网%w |$?9k,_h"R"s7ca
                        For each Element in Page_doc_a51Testing软件测试网d!g` rrGIu%Ae2xj
                                str=str+"  "+Element.outertext51Testing软件测试网$uq:zd*BL
                        Next51Testing软件测试网#[%D:u1~noEVLU
                        Set Page_doc_b=browser("browser").page("index:=0").Object.documentElement.all.tags("input")51Testing软件测试网*x:hg+zZy y
                        For each Element in Page_doc_b
{.`"~*L|7j t273596                                str=str+"  "+Element.value
/D PHYt4C273596                        Next
cf+no~&QVM+v273596                        Set Page_doc_c=browser("browser").Page("index:=0").Object.documentElement.all.tags("SPAN")51Testing软件测试网'a e p,IQ5@g
                        For each Element in Page_doc_c51Testing软件测试网7jpk!G&v oE
                                str=str+"  "+Element.outertext51Testing软件测试网+E*wq-~e d Er-b1DoY~:H
                        Next51Testing软件测试网6e T``Q?
                        Set Page_doc_a=nothing51Testing软件测试网b W~ ]h g Xl
                        Set Page_doc_b=Nothing51Testing软件测试网;x8z G!l0vPI
                        Set Page_doc_c=nothing51Testing软件测试网p{(HS$b
          End if51Testing软件测试网(S_lq^7^;D2z3S;qM
          51Testing软件测试网jSr4y@:E2O
        frame_count=browser("browser").page("index:=0").object.frames.length51Testing软件测试网`{j|*q}X6K!h
        If frame_count<>0 Then51Testing软件测试网T,J-ikXtsdl
            Set Desc = Description.Create()
p^7^S$H Y]!ZD273596                        oDesc("html tag").Value = "iframe"51Testing软件测试网T6} _ PXe7L Lb5f
                        set frame_obj = browser("browser").page("index:=0").ChildObjects(oDesc)  
7i.MRZ Eo"\w273596                        For i=0 to frame_count-1
1VKF2\o(Oy&a273596                                        set Page_doc_a=frame_obj(i).Object.documentElement.all.tags("body")
|)M1Nei g!x273596                                        For each Element in Page_doc_a
8O @R? q?273596                                                        str=str+"  "+Element.outertext51Testing软件测试网 aRZ^,k nP$_!h
                                        next51Testing软件测试网 @XK2J4g q
                                        set Page_doc_b=frame_obj(i).Object.documentElement.all.tags("input")51Testing软件测试网*|FMI;_5dkq
                                        For each Element in Page_doc_b
`LP'TKF&Hs273596                                                        str=str+"  "+Element.value51Testing软件测试网t!Uc"M8j.W9L,jhia9eL
                                        Next
7K7nKgi;D.Y.F273596                                        set Page_doc_c=frame_obj(i).Object.documentElement.all.tags("SPAN")
(| R2qWY.JnuZ273596                                        For each Element in Page_doc_c51Testing软件测试网%?@mk(m.}I
                                                        str=str+"  "+Element.outertext
)I7v8]W(S|Je273596                                        next51Testing软件测试网hf4_:X'`{K
                                        set Page_doc_a=nothing51Testing软件测试网2o6[w#}kkOE
                                        set Page_doc_b=Nothing
u)}3}5i(U273596                                        set Page_doc_c=nothing51Testing软件测试网}B&Z(bp3Lq L
                        Next
A8j&bH9N"|5_'t9]j273596        End If51Testing软件测试网_Vq`'L E;By
        str=str+"  "+browser("browser").WinStatusBar("msctls_statusbar32").getroproperty("text") ' WinStatusBar的对象需要自己添加进对象库
#[h8i2@|ynD3\273596        New_Page_DocExist=RegExpbld (reg,str)
7\7U*h [0]k273596End Function51Testing软件测试网]z/o7R y7T
51Testing软件测试网1L l$gv_)h.e
优势: 方法编写能把标题捕获,状态栏捕获也加进去
r&Y+s^dU&Yl273596       捕获的字样比较全面,较为准确51Testing软件测试网6I'`/`;u*fZ$|kkS
       可移植强51Testing软件测试网'D7Lu0W!R U BT$G[
51Testing软件测试网k)M#V*RN8}
弊端: 使用正则表达式做判断时候时间较长。
w1i"U(D_6g9T27359651Testing软件测试网&c$A8\'{;p7Y2kA
    看完这3个方法后,可能有人会有疑问,那究竟这样真的能够抓到错误吗?在这里,我们只需要再编写多一个截图的功能,并且在跑动脚本过程中只要出现我们定义的“错误”就截图,为的是宁杀错,不放过的精神。值得一提的是,这查找“错误”的方法也适合测试人员在做翻译查找中。因为许多的多语言版本的软件,在翻译方面或者会有漏网之鱼。
)sidkH27359651Testing软件测试网 d-J\r6f#y%Yf)Q
[本帖最后由 假装不在 于 2009-4-29 00:13 编辑]
X]gsu7}*xk273596
,V;Ds/S"m0`27359651Testing软件测试网]6M!};^v{.l W

本文收录于《51测试天地》电子杂志第十三期。

TAG:

 

评分:0

我来说两句