扼杀QTP检查点
其次,知己知彼,方能百战不殆。让我们了解下,QTP检查点的基本工作原理,QTP把某个对象添加到一个“库”中,并记录了它的属性,值等,在运行的时候,把用户指定的属性,值与运行过程中(类似getroproperty)的属性与值进行比较。直到V9.5出台,检查点管理才上升到界面上,并归并于对象库中。至此,检查点的原理在9.5的粉饰下更让人容易接受和入门。51Testing软件测试网S'^$eb%|q%C-}^*M
再次,为什么要添加检查点?因为使用QTP,无论是回归测试,或者其它方面的测试,我们需要一个检查点,一个触发点来达到捕获BUG或者触发事件的目的。因此,渐渐的很多刚用QTP的人便把检查点看成一个能够解决自动化瓶颈的一个出路。所以在一个简单的脚本中,检查点是一个接一个的插进去,琳琅满目。51Testing软件测试网5x{1uIX9Z t(~7X&L
最后,关于检查点的用法,可以在网上搜索下关于这方面的资料,它包括了表、对象、数据库、位图、文本、页面、输入输出值等等。
在这里介绍个简单的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 tag和URL(不要outerhtml之类的),让html tag为a(连接其实有很多中节点方式,需要根据实际去做参数化),URL用正则表达式参数化成"http://(.*)"。
4,然后到对象库中,把刚才的Link("Images")的text做个参数化,例如添加个环境变量Environment“Images_text”。51Testing软件测试网1Q$v5|(s'z8XO O"l!}qZ
5,关于这个对象库中的,我们不要添加太多的属性进去,特别是URL不要加进去,我们就是要通过URL来做检查的(为什么不把对象库中的URL同样也做这种表达的参数化?这点留给细心的读者去思考)
6,运行下面代码:
-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.2和9.5,前者使用的复制黏贴Screen不会跟踪,直到9.X才改善了这个问题。
8,大家很高兴的在Report中看到了若干个检查点的成功报告,而报告的内容就是HTML与URL的检查。至于它的实用性,抛砖引玉。
好了,检查点我们也大概知道个二三,现在我们来说说,这么好的一个检查点,为什么要扼杀它,或者说是对许多QTP用户一个新触发点。
1,在比较稳定的版本QTP8.2中,检查点的添加,保存都是以这一个文件的形式,并未体出一个可维护性高的特点。
2,对象变更,检查点毛病会体现出来,需要重新添加一次检查点或者像在9.5中需要修改属性,因为它的原理基于对象库。
3,项目保存或者移植(被测项目修改),screen丢失或者错乱,会让检查点添加是个让人头痛的问题,因为你需要整理screen或者重新添加,更甚是在8.2中不支持检查点图片跟踪,导致了复制同样的检查点,没办法做到维护。
4,某些检查点的添加是基于screen,当screen出现了第3点中的情况后,项目的维护成为QTP脚本管理员的一个隐痛,自然,琳琅满目的检查点更是让情况发生恶化。
5,检查点的原理基于对象库,因此,对象库中的毛病也会体现出现,维护,移植,管理...
6,框架的可拓展性,因为检查点的特点,导致了它的添加必须基于录制,过渡依赖于Action的使用。会让检查点的添加不能在单独的Function
中使用而。
7,功能局限性,检查点虽然提供了哪么多类型的检查点,但实际上它能做到的或者是读者想要的,远远不只这些东西。
那么,不用检查点,我们有更好的方法去解决吗?我们用检查点干什么?就是为了发现包括回归过程,测试过程中找到与预期结果不同的页面元素。考虑到重用性、可维护性、框架拓展性,我们采用了Function的编写。这并不是舍简求繁,路需要走得更远,这是一个积累的过程。在这里简单举1,2个例子。
'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
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点写成函数。首先,针对这个错误的比较,我们的前提是错误类型字眼的出现,为此我们先编写一个判断正则表达式的函数。
' patrn 正则表达式
regEx, retVal ' 建立变量。
Set regEx = New RegExp ' 建立正则表达式。
regEx.Pattern = patrn ' 设置模式。
regEx.IgnoreCase = true ' 设置是否区分大小写。 retVal = regEx.Test(strng) ' 执行搜索测试。
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
end if
但在第2点中,需要提醒大家的是,捕获这个错误的URL,不仅仅是当前页面的URL,我们还需要取出在页面中所有frame的URL做对比。
' 参数
公司内部自定义的错误页面跳转URL,可以写成数组之类去进行比较
Set FramesObj =browser("Google").Page("Google").Object.frames
For i=0 to FramesObj.length-1
End If
Next
:
再次,我们针对第三点,我们查错的标准是当前页面中是否出现了类似第1点中的错误字样:"错误|error|无法"。但是如何实现呢,在这里简单介绍3个方法。
' QTP_DocIsLive 通过TextUtil 对象判断页面是否存在某个特定错误字样
Public Function QTP_DocIsLive()
Dim Src_text,patrn
Src_text=TextUtil.GetText(0, 20, 20, 2000, 2000) '窗口的大小需要根据实际去定义
patrn="错误|error|无法
Exit Function
End If
QTP_DocIsLive=false
优势:原理简单,甚至能查找到不可预知的msgbox中的内容。
' New_Page_Docfind 通过IE 自带查找功能判断页面是否存在某个特定错误字样
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:
标题搜索
日历
|
|||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
1 | 2 | 3 | 4 | 5 | 6 | ||||
7 | 8 | 9 | 10 | 11 | 12 | 13 | |||
14 | 15 | 16 | 17 | 18 | 19 | 20 | |||
21 | 22 | 23 | 24 | 25 | 26 | 27 | |||
28 | 29 | 30 |
我的存档
数据统计
- 访问量: 30895
- 日志数: 71
- 建立时间: 2009-09-03
- 更新时间: 2012-02-11