User-defined utilities

At present there are two kinds of utilities: AXSUtility and UserUtility. They are Python modules whose structure will be explained in more detail below. To be used, the utilities have to be saved in the utilities directory (as shown in the menu Options ‣ Settings ‣ Directories) or a sub-directory of that. You can find examples of the respective kinds of utilities in the ecu.test installation directory at Templates/DefaultData/Utilities/ExampleUtilities. You can have the basic structure of a utility generated by means of the Utility wizard.

AXSUtility

An AXSUtility can be inserted as a test step. For doing so the utility is mapped on itself i.e. the AXSUtility provides the interface and the implementation.

The advantage is that with such a utility the user just has to write the interface and implement the run () method. The interface describes the input parameters and the return values. Then the parameters can be accessed within the run () method by reading and writing. Everything else (dialog, serialization, reporting etc.) is generated automatically by ecu.test.

Example supplied

In tab Utilities there is, at examples, the AXSUtility “SimpleCalculationExample” for demonstration. Should that example not yet be available they can be copied into the selected workspace as described in the chapter Workspace creation.

../_images/AXSUtility_1.png

In the operation there is a choice between addition, subtraction, multiplication and division. The operation selected will be applied in execution to the two operands a and b.

By a right click on “SimpleCalculationExample” you can select Edit to have a look at implementation. Alternatively, that editor can also be reached by the Utility Wizard.

Generation of an AXSUtility

The second entry in the Utility Wizard:

Interface definition

In method GetInterface(cls) the interface of the AXSUtility must now be defined. The arguments and return values are described as constraints.

At present it is only possible to work with scalar values (that is with simple types of data such as numbers or texts).

  • NumericType

    a number with an optional physical unit. The constructor expects four parameters:

    def __init__(self, name, min, max, step)

    The first parameter defines the name. Additional optional parameters define a lower limit, an upper limit and an increment which have to be complied with later on. If None is passed the limitation does not apply.

    Then the unit can be specified via the method

    def SetUnitFromStr(self, unitName)

    using the units text representation as displayed in ecu.test.

    The initial value to be shown if the utility is added to the test case can be specified using the method

    def SetDefaultValue(self, defaultValue)

    If the value is not specified explicitly, the minimum value or 0 is used.

  • TextType

    A text value. The constructor expects only the name as a parameter.

    def __init__(self, name)

    There is the possibility of indicating a range for the selection of a value by means of

    def AddTextEntry(self, entry)

    The possible selection is shown in the dialog by a combo box.

    The initial value to be shown if the utility is added to the test case can be specified using the method

    def SetDefaultValue(self, defaultValue)

    If the value is not specified explicitly, the first text value or an empty string is used.

The interface will get the argument constraints via

def AddArgument(self, argument)

and the return constraints via

def AddReturn(self, returnValue).

Implementation

Within the method

def OnRun(self, userExcInst, testEngine)

the user can access via the object userExcInst the input parameters by reading, and the return parameters by writing. userExcInst is an instance of the UserExecInst class which provides the following methods of treating a value (only that is supported at present):

  • def GetArgumentValue(self, name)

  • def GetRawArgumentValue(self, name)

    Retrieval of arguments by name. The first method yields a value object instance, the second one the actual value as number or text.

  • def SetReturnValue(self, name, value)

  • def SetRawReturnValue(self, name, raw value)

    Setting the return values of name value/raw value. The first method expects a parameter wrapped in a value object, the second method the actual value as number or text. An argument not passed/mapped results in None.

Optionally, the methods

def OnPreProcess(self, testEngine)

or

def OnPreProcessEx(self, userExcInst, testEngine)

as well as

def OnPostProcess(self, testEngine)

and

def GetReportInfos(self)

can be overwritten. In OnPreProcessEx, input parameters can be accessed in the same way as in OnRun. However, only parameters to which a constant value is assigned (i.e. without references to test case variables) can be accessed. For each non-hidden occurrence of the utility call in the test case, the OnPreProcessEx method is called once with the respective parameters, disregarding loops, if-then-else etc.

Info

In particular if an AXSUtility is used several times in the test case, the dict returned by GetReportInfos must be held in a list (or deque). This necessity arises due to the fact that if for instance an AXSUtility is used twice, then the OnRun method is executed twice before the method GetReportInfos is called. Directly storing the ReportInfos in a dict it is overwritten during the second call of OnRun. Hence, the subsequent two calls of GetReportInfos will both return the ReportInfos of the second utility execution. In the examples (see section Workspace creation) the correct usage of GetReportInfos is demonstrated by the utility “LinspaceExample”.

After closing the utility wizard, the AXSUtility can be inserted and executed as a test step:

../_images/AXSUtility_3.png

A utility mapped on itself (thus providing the interface and the implementation) is recognizable in the report by the action “UTILITY -> UTL”:

../_images/AXSUtility_2.png

UserUtility

The concrete structure of a UserUtility is explained in the documentation of the UserUtility API. When updating user utilities and reloading them with the menu item “Update user libraries” (shortcut Ctrl+Shift+R), opened packages using them have to be closed and reopened in order for the update to take effect.