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