2008年10月3号
大家好,
已经有一段时间没给大家回信了,对此我非常抱歉。由于公司的业务繁忙所以我一直没有给大家回信,当然我知道不应该拿这个当作借口。
这次,我将给大家讲解一下有关QuickTest Professional的使用。
多数时间,QTP可以自动录制你与应用系统交互的每一步,然而,尽管QTP功能强大,但是当应用界面对象不是标准的时候QTP也是无能为力的。
这是因为对于应用界面不标准的类型,QTP没有关于它的先前的资料,所以当遇到这种问题的时候就不知道如何去解决。正如一个孩子当在一些新的事情上犯错误的时候就不知道怎么去解决。
对于这类型的问题,我们有两种解决办法:
告诉QTP这个新事物的所有相关信息并且解释处理的方法。意思就是说当QTP下次遇到这个新事物的时候,就会自动识别并恰当地使用这个新事物(知道该记录什么和如何去回放这些记录)。让QTP执行这个,你需求使用一个叫做可延长性的功能。然而,我们都知道创建可延长性是有一定难度的而且它会限制QTP添加项的使用。
你创建一个回放的解决方案。意思是当你录制的时候QTP任然不知道你对这个应用的操作,所以不会恰当的生成脚本但是在录制的过程中QTP能够和应用交互。为了实现这个功能,你必须写自定义的函数并且详细的描述每一步的操作。这类型的解决方案往往使你的脚本更容易理解。下面我们会对这种解决方案进行详细的介绍。
因此,首先,我们使用QTP录制一段脚本:
Window(“Paint”).WinObject(“Colors”).Click 72,33
Window(“Paint”).WinObject(“Tools”).Click 21,148
Window(“Paint”).WinObject(“Afx:1000000:8″).Click 48,99
Window(“Paint”).WinObject(“Afx:1000000:8″).Drag 100,48
Window(“Paint”).WinObject(“Afx:1000000:8″).Drop 137,100
Window(“Paint”).WinObject(“Afx:1000000:8″).Drag 52,98
Window(“Paint”).WinObject(“Afx:1000000:8″).Drop 135,98
Window(“Paint”).WinObject(“Afx:1000000:8″).Drag 47,100
Window(“Paint”).WinObject(“Afx:1000000:8″).Drop 47,189
Window(“Paint”).WinObject(“Afx:1000000:8″).Drag 47,189
Window(“Paint”).WinObject(“Afx:1000000:8″).Drop 134,188
Window(“Paint”).WinObject(“Afx:1000000:8″).Drag 137,102
Window(“Paint”).WinObject(“Afx:1000000:8″).Drop 135,188
Window(“Paint”).WinObject(“Colors”).Click 134,30
Window(“Paint”).WinObject(“Tools”).Click 15,174
Window(“Paint”).WinObject(“Tools”).Click 31,261
Window(“Paint”).WinObject(“Afx:1000000:8″).Drag 82,144
Window(“Paint”).WinObject(“Afx:1000000:8″).Drop 102,187
如果你录制了这段脚本,你将看到QTP画了一个院长的图画,但是我们看这段脚本根本没有一点标示是画这个图画。同时你也注意到这个图画中丢失了一个元素,我没有忘记这个元素但是QTP却没有录制它。
现在,让我们看一下我们如何提高我们的脚本并且使我们的录制方案比QTP目前所能及的做的更好。
首先行为第一,你想让你的脚本看起来像什么呢?我个人的意见是,像下面的这段脚本就是好的:
SelectColor“red”
SelectTool“line”
DrawLine 100, 48, 137, 100
DrawLine 52, 98, 135, 98
…
SelectColor“blue”
SelectTool“rectangle”
DrawRectangle 82, 144, 102, 187
如果你像我,仅仅读了上面的一段脚本,你理解QTP做了什么,画了一根红色的线,一个蓝色的矩形等等[但是,你任然不会知道最后这个图画是什么样子]。你相信吗,这就是向前的方式?是的,的却如此,让我们出发。
首先,我们需要去了解QTP从应用中获悉什么。为了知道这个,我们使用间谍工具去监视QTP怎样识别你的对象。你将注意到所有的工具栏(工具和颜色)都作为一种对象被识别,同时QTP不能识别个别的按钮但是你能看到QTP识别了这种对象并作为WinObjects。
当你在应用中看到WinObjects的时候,你应该立刻意识到,这些是QTP不能识被的对象。事实如此,WinObjects是当QTP不了解这个对象时用来使用的一种类型。如果QTP了解对象的一些属性,QTP将把这些对象分类为一些其他的对象(WinEdit, WinButton, WinToolbar,等等.)因此,对选项里的任一项,QTP有一种类型用来标示它不识别这个对象。WinObject为windows的对象,WebElement为Web的对象,JavaObject为Java对象,SwfObject为.Net对象等等。
因此,现在我们知道QTP只识别3个对象,这3个对象全是WinObjects:工具栏,颜色栏和画布(画图区域)。对于我们的回放,这些信息就已经足够了,因为我们总是通过使用点击工具栏里的按钮并使用相应的提示进行操作,只要这个按钮在工具栏里不移动就可以。
现在我们做一个简单的例子:
当我们选择了这个线条工具,QTP识别下面的状态:
Window(“Paint”).WinObject(“Tools”).Click 21,148
如果你试图努力,你可能得到一些和这些提示不同的值但是他们基本上一致,实际上,你可以点击任何地方只要他在工具栏的范围之内并且你可以选择即可。
现在,我们写一些和以下相似的事情:
SelectTool“Line”
如果你现在就这样执行脚本,QTP将提示它不理解关于选择工具栏的任何信息。而且QTP将通过“配错类型”错误提示显示出来。如果你同意的话,告诉QTP怎样去做。
我们需要创建一个和选择工具栏相同名字的程序,并且规定当执行程序时相应的做什么。
Sub SelectTool(ToolName)
If ToolName = “Line” Then
Window(“Paint”).WinObject(“Tools”).Click21,148
Else
MsgBox “Invalid tool name.”
End If
End Sub
SelectTool “Line”
如果你再次执行这段脚本,你将注意到QTPP不会验证关键字是否正确,反而直接调用Line工具。
因此,现在你可以在你的函数里添加许多新的灵活的工具:
Sub SelectTool(ToolName)
Select Case ToolName
Case “Line”
Window(“Paint”).WinObject(”Tools”).Click16,142
Case “Curve”
Window(“Paint”).WinObject(”Tools”).Click 41,143
Case “Rectangle”
Window(“Paint”).WinObject(”Tools”).Click 16,165
Case “Polygon”
Window(“Paint”).WinObject(”Tools”).Click 41,166
Case Else
Reporter.ReportEvent micFail, “SelectTool”, “The tool ‘” & ToolName & “‘ does not exist.”
End Select
End Sub
SelectTool “Line”
SelectTool “Rectangle”
SelectTool “Line”
好了,现在你得到了图片并且你也知道如果新建SelectColor程序了。
但是,让我们看的远一点,因为我们写的程序并不完美。当我们写函数或程序时,我们可以使用变量让它更灵活而且我们可以参数化工具名称实现。然而,一个函数或是程序可以完全独立于外部数据除了通过参数传递数据。并且在当前情况下,SelectTool是依靠Window(”Paint”).WinObject(”Tools”)。所以,为了完善我们的函数,我们从这种方式重写:
Sub SelectTool(ToolObject, ToolName)
Select Case ToolName
Case “Line”
ToolObject.Click 16,142
Case “Curve”
ToolObject.Click 41,143
Case “Rectangle”
ToolObject.Click 16,165
Case “Polygon”
ToolObject.Click 41,166
Case Else
Reporter.ReportEvent micFail, “SelectTool”, “The tool ‘” & ToolName & “‘ does not exist.”
End Select
End Sub
SelectTool Window(“Paint”).WinObject(“Tools”), “Line”
SelectTool Window(“Paint”).WinObject(“Tools”), “Rectangle”
SelectTool Window(“Paint”).WinObject(“Tools”), “Line”
现在,我们通过添加一个新的参数从工具对象中移除附属,增加句法的结构复杂性。但是QTP有一个特性就是容许我们给QTP对象注册一个函数或者程序。通过做这些,我们告诉QTP对象现在是一个新的函数:
SubSelectTool(ToolObject, ToolName)
Select Case ToolName
Case “Line”
ToolObject.Click 16,142
Case “Curve”
ToolObject.Click 41,143
Case “Rectangle”
ToolObject.Click 16,165
Case “Polygon”
ToolObject.Click 41,166
Case Else
Reporter.ReportEvent micFail, “SelectTool”, “The tool ‘” & ToolName & “‘ does not exist.”
End Select
End Sub
RegisterUserFunc “WinObject”, “SelectTool”, “SelectTool”
Window(“Paint”).WinObject(“Tools”).SelectTool “Line”
Window(“Paint”).WinObject(“Tools”).SelectTool “Rectangle”
Window(“Paint”).WinObject(“Tools”).SelectTool “Line”
现在,我们知道在我们的工具栏里如何去选择一个项目,让我们看一下在画布里画图。之前,我们规定和下面的代码相似是理想的:
SelectColor “red”
SelectTool “line
DrawLine 100, 48, 137, 100
So, now we need to draw a line:
Sub DrawLine(CanvasObject, StartX, StartY, EndX, EndY)
CanvasObject.Drag StartX, StartY
CanvasObject.Drop EndX, EndY
End Sub
RegisterUserFunc “WinObject”, “DrawLine”, “DrawLine”
Window(“Paint”).WinObject(“Afx:1000000:8″).DrawLine 44, 34, 128, 34
完整脚本如下:
Dim dicTools
Set dicTools = CreateObject(“Scripting.Dictionary”)
dicTools.Add “line”, Array(16, 142)
dicTools.Add “curve”, Array(41, 142)
dicTools.Add “rectangle”, Array(16, 165)
dicTools.Add “polygon”, Array(31, 165)
Dim dicColors
Set dicColors = CreateObject(“Scripting.Dictionary”)
dicColors.Add “black”, Array(42, 14)
dicColors.Add “white”, Array(42, 30)
dicColors.Add “red”, Array(72, 33)
dicColors.Add “yellow”, Array(89, 33)
dicColors.Add “green”, Array(103, 33)
dicColors.Add “blue”, Array(135, 33)
Sub SelectTool(ByRef objTool, ByVal ToolName)
ToolName = LCase(ToolName)
If dicTools.Exists(ToolName) Then
objTool.Click dicTools(ToolName)(0), dicTools(ToolName)(1)
Reporter.ReportEvent micPass, “SelectTool”, “The tool ‘” & ToolName & “‘ has been selected.”
Else
Reporter.ReportEvent micFail, “SelectTool”, “The tool ‘” & ToolName & “‘ does not exist.”
End If
End Sub
Sub SelectColor(ByRef objColor, ByVal ColorName)
ColorName = LCase(ColorName)
If dicColors.Exists(ColorName) Then
objColor.Click dicColors(ColorName)(0), dicColors(ColorName)(1)
Reporter.ReportEvent micPass, “SelectTool”, “The color ‘” & ColorName & “‘ has been selected.”
Else
Reporter.ReportEvent micFail, “SelectTool”, “The color ‘” & ColorName & “‘ does not exist.”
End If
End Sub
Sub DrawLine(CanvasObject, StartX, StartY, EndX, EndY)
CanvasObject.Drag StartX, StartY
CanvasObject.Drop EndX, EndY
End Sub
Sub DrawRectangle(CanvasObject, StartX, StartY, EndX, EndY)
CanvasObject.Drag StartX, Start