简体   繁体   English

如何使用在测试运行时确定的类来创建特定GUI类的测试对象?

[英]How can I create a test object of a specific GUI class with the class determined at test runtime?

The idea is to have a GUI class name (like JavaRadioButton ) in a string variable, and instantiate a test object of that type using a Description object. 想法是在字符串变量中具有GUI类名称(例如JavaRadioButton ),并使用Description对象实例化该类型的测试对象。 Like in: 像:

Dim Descr: Set Descr=Description.Create
Descr.Add "property1", "value"
Descr.Add "property2", "value"
Descr.Add "property3", "value"
Dim MyTO: Set MyTO=JavaRadioButton (Descr)

but with the GUI class ( JavaRadioButton in this case) being parameterized , ie I have the string "JavaRadioButton" in a variable and want to create a testobject of the GUI class that is contained in that variable. 但是已 对GUI类(在这种情况下为JavaRadioButton )进行了参数化 ,即我在变量中具有字符串"JavaRadioButton" ,并希望创建该变量中包含的GUI类的测试对象。

An obvious attempt is to use the "micclass" property, which reports the GUI class name of a test object: 一个明显的尝试是使用"micclass"属性,该属性报告测试对象的GUI类名称:

Dim ClassName: ClassName="JavaRadioButton"
Dim Descr: Set Descr=Description.Create
Descr.Add "property1", "value"
Descr.Add "property2", "value"
Descr.Add "property3", "value"
Descr.Add "micclass", ClassName
Dim MyTO: Set MyTO=JavaObject (Descr)

However, afterwards MyTO still is just a JavaObject . 然而,事后MyTO仍然只是一个JavaObject For example, it does not support the .Set method as a JavaRadioButton would. 例如,它不像JavaRadioButton那样支持.Set方法。

My current "solution" would be to construct a string that contains the assignment, and evaluate this using ExecuteGlobal (or Eval , as shown here): 我当前的“解决方案”是构造一个包含赋值的字符串,并使用ExecuteGlobal (或Eval ,如此处所示)对其进行评估:

Dim ClassName: ClassName="JavaRadioButton"
Dim Descr: Set Descr=Description.Create
Descr.Add "property1", "value"
Descr.Add "property2", "value"
Descr.Add "property3", "value"
Descr.Add "micclass", ClassName
Dim MyTO: Set MyTO=Eval (ClassName & "(Descr)")

This seems to work, as long as ClassName and Descr are reachable for Eval , which sometimes is clumsy to achieve. 只要Eval可以访问ClassNameDescr ,这似乎是可行的,但有时实现起来很笨拙。 And it requires error handling code, if you want to catch errors. 如果您想捕获错误,它需要错误处理代码。

Isn´t there a way to do this without creating a string containing sourcecode, and executing it? 没有创建包含源代码的字符串并执行它,有没有办法做到这一点?

Note I added the VBScript tag because that´s QTP´s scripting language, however this question is QTP-specific. 注意我添加了VBScript标记,因为它是QTP的脚本语言,但是这个问题是QTP特有的。

I do not have QTP at hand, but you could try something like this were I launch the assumption that the objects are actually functions that return an object with the same name of that function. 我手头没有QTP,但是如果我假设这些对象实际上是返回与该函数同名的对象的函数,则可以尝试类似的操作。

Dim ClassName: ClassName="JavaRadioButton"
Dim Descr: Set Descr=Description.Create
Descr.Add "property1", "value"
Descr.Add "property2", "value"
Descr.Add "property3", "value"
Descr.Add "micclass", ClassName

Dim constructor : Set constructor = GetRef(ClassName)
Dim MyTO: Set MyTO=constructor(Descr)

Could you try that and let me know what it is doing? 您可以尝试一下,让我知道它在做什么吗? I am seriously curious. 我很好奇。


EDIT 编辑

Basis for the assumption: The JavaScriptButton is a function that returns an object. 假设的依据:JavaScriptButton是一个返回对象的函数。 The function can support arguments. 该函数可以支持参数。 This is a way to implement a builder or even an abstract factory pattern: 这是一种实现生成器甚至是抽象工厂模式的方法:

Option explicit    

Class Duck

    Private sound_
    Public Name      ' public field, refactor to property

    Public Function Init(n, sound)
        sound_ = sound
        Name = n
        Set Init = me
    End Function

    Public Sub Quack()
        msgbox sound_
    End Sub

End Class


Public Function NormalDuck(name)
     Set NormalDuck = (new Duck).Init(name, "quack, quack")
End Function

Public Function RubberDuck(name)
     Set RubberDuck = (new Duck).Init(name, "squick, squick")
End Function

Public Function DecoyDuck(name)
     Set DecoyDuck = (new Duck).Init(name, "")
End Function

dim myDuck
dim duckBuilder
dim duckName, duckType

duckType = InputBox("What kind of duck do you want?", "DuckType", "NormalDuck")
Set duckBuilder = GetRef(duckType)

duckName = InputBox("What will be its name?", "DuckName", "Donald")
Set myDuck = duckBuilder(duckName)

myDuck.Quack

Note: VBScript supports the set o = (new foo).Init(bar) construct, while the QTP "compiler" will return a syntax error. 注意:VBScript支持set o = (new foo).Init(bar)构造,而QTP“编译器”将返回语法错误。 You'll have to split it into two statements in QTP 您必须在QTP中将其拆分为两个语句

This is pretty easy to achieve if you're willing to use ChildObjects rather than regular descriptive programming. 如果您愿意使用ChildObjects而不是常规的描述性编程,则这很容易实现。

Function GetObj(parent, micClass, desc)
    desc.Add "micclass", micClass
    Set children = parent.ChildObjects(desc)
    If children.Count < 1 Then
        Err.Raise 1, "GetObj", "Object not found"
    ElseIf children.Count > 1 Then
        Err.Raise 1, "GetObj", "Description is not unique, found " & children.Count & " matches"
    End If
    Set GetObj = children(0)
End Function

Usage: 用法:

GetObj(oPage, "WebEdit", desc).Set "Set is a specific method"

I don't know how much value this gives you since you still need to have Set as part of the script and not as a string... 我不知道这能给您带来多少价值,因为您仍然需要将Set作为脚本的一部分而不是字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM