Search code examples
qtphp-uftalm

Query component parameters at runtime?


How can I query the parameter names of the parameters of the component currently being executed?

The first idea that comes to mind is to use the UFT automation object and query the .BusinessComponent property, like this:

Dim UFTApp: Set UFTApp=CreateObject ("QuickTest.Application")
Dim Index
Print "BusinessComponent.ParameterDefinitions.Count=" & CStr (UFTApp.BusinessComponent.ParameterDefinitions.Count)
For Index = 1 To UFTApp.BusinessComponent.ParameterDefinitions.Count
    Print CStr (Index) & ": " & UFTApp.BusinessComponent.ParameterDefinitions.Item (Index).Name
Next

Once I have the names, I can call Parameter (<Name>) to get the value. Alternatively, to also get the values, one could use

Print "BusinessComponent.ParameterDefinitions.GetParameters.Count=" & CStr (UFTApp.BusinessComponent.ParameterDefinitions.GetParameters.Count)
For Index = 1 To UFTApp.BusinessComponent.ParameterDefinitions.GetParameters.Count
Print CStr (Index) & ": " & UFTApp.BusinessComponent.ParameterDefinitions.GetParameters.Item (Index).Value
Next

This works fine if the component is executed standalone.

But! If you execute the component as part of a BPT, the .Count methods return zero.

It seems like the ParameterDefinitions collection is not set in this case. (Note .BusinessComponent.Name does return the correct value, so the container instance itself indeed is set properly.)

So how can I iterate over the current component´s parameters if I don't know the parameter names in advance?

This question comes up once you create generic library code that is not allowed to "know" the names in advance.

I am 99% sure the same question applies to QTP, so I included that tag, too.


Solution

  • Turns out that the primary problem is that BusinessComponent.ParameterDefinitions is not set up properly, at least not in all cases.

    To get the parameter definitions, we need to look into ALM´s API.

    There, the main problem is that we do not know which component to query, i.e. we don´t know which is the currently running component.

    The only reliable way I found to get the current component´s name (and ALM path) is to inspect UFTApp.BusinessComponent.Location. (UFTApp.BusinessComponent.Name is unreliable, because some versions of UFT seem to use the component ID to look up the component name in the test plan, which yields some (unpredictable) test´s name, and not the correct components name.)

    So to enumerate the current component´s parameters, I now look up the component´s path (obtained from .Location) in ALM´s component folder factory, filter the resulting ALM folder so the filtered list only contains the component with the searched name (also obtained from .Location), and use ALM´s API to query the parameters.

    That seems to work fine as long as you don´t use version control, or you make sure you check-in the change first after modifying parameters before you run below code.

    Since the ALM API does not understand the “[ALM] “ prefix that UFT wants (and which is included in the BusinessComponent.Location property value), some quick & dirty string parsing is required to build the path (or name) to search for.

    Resulting code:

    ' Global shorthand for CreateObject ("QuickTest.Application") (UFT OTA-interface)
    Dim UFTApp: Set UFTApp=GetObject ("","QuickTest.Application")
    
    
    '@Description Name including path of current UFT component?
    Public Function GetCurrentModuleName ()
        Dim Result: Result=GetUFTCurDoc.Location
        Result=Right (Result, Len (Result)-Len ("[ALM] "))
        GetCurrentModuleName=Result
    End Function
    
    '@Description Component name (without path) of the specified component?
    '   ModuleName: Component name including ALM path
    Public Function GetModuleName (ByVal ModuleName)
        ' Use split with backslash, then return only the last element
        Dim Parts: Parts=Split (ModuleName, "\", -1, vbBinaryCompare)
        GetModuleName=Parts(UBound (Parts))
    End Function
    
    '@Description ALM path of the specified componentname (including path) (returned value does not end with a backslash)?
    '   ModuleName: Component name (including path) in ALM
    Public Function GetModulePath (ByVal ModuleName)
        GetModulePath=Left (ModuleName, Len(ModuleName)-Len (GetModuleName (ModuleName))-1)
    End Function
    
    
    Dim ComponentFilter: Set ComponentFilter=QCUtil.QCConnection.ComponentFolderFactory.FolderByPath (GetModulePath (GetCurrentModuleName ())).ComponentFactory.Filter
    ComponentFilter ("CO_NAME")="""" & GetModuleName (GetCurrentModuleName ()) & """"
    Dim Param
    For Each Param in ComponentFilter.NewList().Item(1).ComponentParamFactory.NewList("")
        Print Param.Name
    Next
    

    Since that answers my original question perfectly, I´ll accept my own answer, as bad as this might look, so everybody with the same problem can use this approach.