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

StackOverflow https://stackoverflow.com/questions/21554746

  •  06-10-2022
  •  | 
  •  

Question

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. 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, i.e. I have the string "JavaRadioButton" in a variable and want to create a testobject of the GUI class that is contained in that variable.

An obvious attempt is to use the "micclass" property, which reports the GUI class name of a test object:

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. For example, it does not support the .Set method as a JavaRadioButton would.

My current "solution" would be to construct a string that contains the assignment, and evaluate this using ExecuteGlobal (or Eval, as shown here):

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. 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.

Was it helpful?

Solution 2

This is pretty easy to achieve if you're willing to use ChildObjects rather than regular descriptive programming.

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...

OTHER TIPS

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.

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. 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. You'll have to split it into two statements in QTP

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top