我试图将测试放在HP Unified Functional Testing中 程序员的方式。 对于那些不知道的人,该工具使用VBScript作为其驱动程序。
因为我想在多个UFT操作中使用来自同一DataTable的数据 - 并且因为全局表已经有一组不同的数据 - 我想从外部文件中检索数据。 UFT很乐意支持这个功能。
我目前的计划是,根据我正在进行的测试, 我将遍历该表中的一系列行。
这是我提出的脚本:
' targets the local sheet, but
' not the same value as dtLocalSheet
Const sheetNum = 2
dim sheetRowCount
DataTable.ImportSheet "PersonFile.xlsx", 1, sheetNum
sheetRowCount = DataTable.GetSheet(sheetNum).GetRowCount
dim firstRow, lastRow
firstRow = Parameter("FirstPersonIndex")
lastRow = Parameter("LastPersonIndex")
If sheetRowCount < lastRow Then
lastRow = sheetRowCount
End If
If sheetRowCount >= firstRow Then
Dim i
For i = firstRow To lastRow
DataTable.SetCurrentRow i
' begin payload
MsgBox(DataTable.Value("LastName", dtLocalSheet))
' end payload
Next
End if
我不想重复所有这些样板 每次我想使用这种模式。 我真的很喜欢这样的东西:
在函数库中:
sub LoopThroughSheetAnd(sheetFile, doThis)
' targets the local sheet, but
' not the same value as dtLocalSheet
Const sheetNum = 2
dim sheetRowCount
DataTable.ImportSheet sheetFile, 1, sheetNum
sheetRowCount = DataTable.GetSheet(sheetNum).GetRowCount
dim firstRow, lastRow
firstRow = Parameter("FirstRow")
lastRow = Parameter("LastRow")
If sheetRowCount < lastRow Then
lastRow = sheetRowCount
End If
If sheetRowCount >= firstRow Then
Dim i
For i = firstRow To lastRow
DataTable.SetCurrentRow i
call doThis()
Next
End if
end sub
在最初的行动......
sub Payload1()
MsgBox(DataTable.Value("LastName", dtLocalSheet))
end sub
LoopThroughSheetAnd "PersonFile.xlsx", Payload1
在单独的行动中,3或4步之后......
sub Payload2()
' compare the data against another data source
end sub
LoopThroughSheetAnd "PersonFile.xlsx", Payload2
上述代码在VBScript中不起作用。
抛出类型不匹配错误
一旦我们尝试将Payload1
作为参数传递。
如何才能在VBScript中合理地解决这个问题? 如果答案也适用于UFT,则奖励积分。
答案 0 :(得分:5)
您可以使用GetRef()
函数将函数作为参数传递。这是一个实用程序map
函数,就像您在JavaScript中找到接受数组并为数组的每个元素调用函数一样:
Sub Map(a, f)
Dim i
For i = 0 To UBound(a)
' Call a function on each element and replace its value with the function return value
a(i) = f(a(i))
Next
End Sub
Map MyArray, GetRef("SomeFunc")
现在您可以编写SomeFunc
以便它对值进行操作并返回更新的值:
Function SomeFunc(i)
SomeFunc = i + 1
End Function
这很好用。 map
使用函数&#34;指针&#34;调用SomeFunc
我们过去了。
您可以使用LoopThroughStreetAnd
函数执行类似操作:
LoopThroughStreetAnd "PersonFile.xlsx", GetRef("Payload2")
答案 1 :(得分:2)
答案 2 :(得分:0)
使用对象时,可以将对方法的调用包装在对象中,然后可以传递该对象。 (这大约已经是其他语言所发生的事情,您只需在VBScript中手动进行操作即可。)
唯一的问题是调用此方法的任何方法都必须是Public
。
我将使用诸如“ Func1”,“ Func2”,“ Action1”,“ Action2”等之类的命名方案,具体取决于函数的可用性以及它们是否返回值。
Dim s : Set s = New Something : s.Run
Class Something
Public Sub HowToPassMe(pValue)
WScript.Echo pValue
End Sub
Public Sub Run
Dim action : Set action = New Action1Wrapper
Set action.Target = Me
Dim se : Set se = New SomethingElse
se.DoSomethingElse action
End Sub
End Class
Class SomethingElse
Public Sub DoSomethingElse(pAction1)
pAction1.Action1("something")
End Sub
End Class
Class Action1Wrapper
Private mTarget
Public Property Set Target(value) : Set mTarget = value : End Property
Public Sub Action1(p1)
mTarget.HowToPassMe(p1)
End Sub
End Class
使用Execute
,Action1Wrapper
也可以像下面这样写。您还可以编写工厂类以方便使用。
Class Action1Wrapper
Private mTarget
Public Property Set Target(value) : Set mTarget = value : End Property
Private mName
Public Property Let Name(value) : mName = value : End Property
Public Sub Action1(p1)
Execute "mTarget." & mName & "(p1)"
End Sub
End Class
Class Action1Factory_
Public Function Create(pTarget, pName)
Dim a1 : Set a1 = New Action1Wrapper
Set a1.Target = pTarget
a1.Name = pName
Set Create = a1
End Function
End Class
Dim Action1Factory : Set Action1Factory = New Action1Factory_
用作:
Dim action : Set action = Action1Factory.Create(Me, "HowToPassMe")
Dim se : Set se = New SomethingElse
se.DoSomethingElse action
答案 3 :(得分:-1)
当我写这个问题时,我的记忆变得不合时宜, 我开始研究我曾经发现的“特征”。
这在HP UFT的上下文中无效, 但如果您正在运行cscript,或使用Classic ASP, 你可以延迟声明一个函数,或者替换以前的声明, 改变它的运作方式。
VBScript允许您声明相同的函数或子例程 在程序中多次。 它将最后一个声明视为正确声明。
你可以通过物理分离在cscript和ASP中解决这个问题 不同版本的功能, 这样一个人就不会被另一个人摧毁。 你必须要小心,不要把两者放在彼此附近, 或者你(继任者)可能有动脉瘤试图调试结果。
老实说,你可能会更好地以其他方式重构你的代码。
现在,在免责声明的情况下, 以下示例适用于cscript或wscript。
因为无论如何这都不适用于UFT,我会从头开始写。
在 WrapperSub.vbs :
中' Sub WrapperSub_Payload doesn't exist in this file.
' It must be declared by the calling file or the program will crash.
Sub WrapperSub()
wscript.echo("This begins the wrapper.")
WrapperSub_Payload
wscript.echo("This ends the wrapper.")
End Sub
在 WrapperSubUseA.vbs :
With CreateObject("Scripting.FileSystemObject")
call ExecuteGlobal(.openTextFile("WrapperSub.vbs").readAll())
End With
Sub WrapperSub_Payload
wscript.echo("This is payload A.")
End Sub
WrapperSub
在 WrapperSubUseB.vbs :
With CreateObject("Scripting.FileSystemObject")
call ExecuteGlobal(.openTextFile("WrapperSub.vbs").readAll())
End With
Sub WrapperSub_Payload
wscript.echo("This is payload B.")
End Sub
WrapperSub
>cscript wrappersubusea.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
This begins the wrapper.
This is payload A.
This ends the wrapper.
>cscript wrappersubuseb.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
This begins the wrapper.
This is payload B.
This ends the wrapper.
请注意,如果是WrapperSub_Payload
的占位符
在源文件中声明,
该占位符将始终执行而不是预期的子例程。
这可能是由于ExecuteGlobal
在解析当前文件后执行,
导致占位符在本地声明后加载。
当您在UFT中尝试此操作时 -
将WrapperSub.vbs的内容放在函数库中 -
函数库正确地忽略了调用者的作用域。
然后它将失败,因为范围中不存在WrapperSub_Payload
。