Benutzerdefinierte Utilities

Derzeit existieren zwei Arten von Utilities: AXSUtility und UserUtility. Dabei handelt es sich um Python-Module, deren Aufbau in den folgenden Abschnitten näher erläutert wird. Um die Utilties verwenden zu können, müssen diese im Utilities-Verzeichnis (wie im Menü Optionen ‣ Einstellungen ‣ Verzeichnisse angegeben) oder einem Unterverzeichnis davon gespeichert werden. Beispiele zu den jeweiligen Utilityarten finden Sie im ecu.test Installationsverzeichnis unter Templates/DefaultData/Utilities/ExampleUtilities. Über den Utility Wizard können Sie sich ein Grundgerüst für ein Utility generieren lassen.

AXSUtility

Es besteht die Möglichkeit, ein AXSUtility als Testschritt einzufügen. Dabei wird das Utility auf sich selbst gemappt, d.h. das AXSUtility stellt das Interface und die Implementierung bereit.

Der Vorteil ist, dass der Benutzer bei einem solchen Utility nur noch das Interface schreiben und die Run()-Methode implementieren muss. Das Interface beschreibt die Eingangsparameter und die Rückgabewerte. Innerhalb der Run()-Methode kann dann auf die Parameter lesend und schreibend zugegriffen werden. Alles weitere (Dialog, Serialisierung, Reporting, …) wird automatisch von ecu.test erstellt.

Mitgeliefertes Beispiel

Im Tab Utilities existiert unter Beispiele das AXSUtility „SimpleCalculationExample“ zur Demonstration. Sollte dies hier noch nicht vorhanden sein, können Sie wie im Abschnitt Workspace Erstellung beschrieben die Beispiele in den gewählten Workspace kopieren.

../_images/AXSUtility_1.png

Man kann bei der Operation zwischen Addition, Subtraktion, Multiplikation und Division wählen. Die gewählte Operation wird bei der Ausführung auf die beiden Operanden a und b angewandt.

Bei einem Rechtsklick auf „SimpleCalculationExample“ kann bearbeiten ausgewählt werden, um die Implementierung zu betrachten. Alternativ ist dieser Editor auch über den Utility Wizard erreichbar.

Erstellung eines AXSUtility

Der zweite Eintrag im Utility Wizard:

Interfacedefinition

In der Methode GetInterface(cls) muss nun das Interface des AXSUtility definiert werden. Die Argumente und Rückgabewerte werden als Constraints beschrieben.

Derzeit ist es nur möglich mit skalaren Größen (also einfachen Datentypen wie Zahlen oder Texten) zu arbeiten.

  • NumericType

    Eine Zahl. Wahlweise mit einer physikalischen Einheit. Der Konstruktor erwartet vier Parameter:

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

    Der erste Parameter definiert den Namen. Zusätzlich können eine optionale Unter- und Obergrenze und eine Schrittweite angegeben werden, welche eingehalten werden müssen. Wird None übergeben, dann entfällt die Beschränkung. Über die Methode

    def SetUnitFromStr(self, unitName)

    kann anschließend die Einheit gesetzt werden, wobei hier die Einheit als Text (wie in ecu.test angezeigt) angegeben werden muss.

    Über die Methode

    def SetDefaultValue(self, defaultValue)

    kann der initiale Wert beim Einfügen des Utilities festgelegt werden. Wird dieser Wert nicht explizit angegeben, so werden der Minimalwert oder 0 verwendet.

  • TextType

    Ein Textwert. Der Konstruktor erwartet ausschließlich den Namen als Parameter:

    def __init__(self, name)

    Es besteht die Möglichkeit über

    def AddTextEntry(self, entry)

    einen Wertebereich für die Auswahl eines Wertes anzugeben. Die mögliche Auswahl wird im Dialog durch eine Combobox angezeigt.

    Über die Methode

    def SetDefaultValue(self, defaultValue)

    kann der initiale Wert beim Einfügen des Utilities festgelegt werden. Wird dieser Wert nicht explizit angegeben, so werden der erste Textwert oder eine leere Zeichenkette verwendet.

Dem Interface werden über

def AddArgument(self, argument)

die Argumentenconstraints bzw. über

def AddReturn(self, returnValue)

die Rückgabeconstraints übergeben.

Die Implementierung

Innerhalb der Methode

def OnRun(self, userExcInst, testEngine)

kann der Benutzer mittels des Objekts userExcInst lesend auf die Eingabeparameter und schreibend auf die Rückgabewerte zugreifen. userExcInst ist eine Instanz der Klasse UserExecInst, welche folgende Methoden zur Behandlung eines Values-Objekts (nur dieser wird derzeit unterstützt) bereitstellt:

  • def GetArgumentValue(self, name)

  • def GetRawArgumentValue(self, name)

    Abfragen der Argumente anhand deren Namen. Die erste Methode liefert den Wert gekapselt in einem Value-Objekt zurück, die zweite den konkreten Wert als Zahl oder Text.

  • def SetReturnValue(self, name, value)

  • def SetRawReturnValue(self, name, rawvalue)

    Setzen der Rückgabewerte mit den Namen value/rawvalue. Die erste Methode erwartet einen Parameter der in einem Value-Objekt gekapselt ist, die zweite Methode den konkrete Wert als Zahl oder Text. Ein nicht übergebenes/gemapptes Argument entspricht None.

Optional können noch die Methoden

def OnPreProcess(self, testEngine)

oder

def OnPreProcessEx(self, userExcInst, testEngine)

sowie

def OnPostProcess(self, testEngine)

und

def GetReportInfos(self)

überschrieben werden. In OnPreProcessEx ist dabei der Zugriff auf die Eingabeparameter auf die selbe Weise wie in OnRun möglich. Es können jedoch nur Parameter abgefragt werden, für die ein konstanter Wert (d.h. ohne Zugriff auf Testfallvariablen) übergeben wird. Die Methode OnPreProcessEx wird dabei für jedes nicht ausgeblendete Vorkommen des Utility-Aufrufs im Testfall einmal mit der entsprechenden Parametrierung aufgerufen, ohne Rücksicht auf Loops, If-Then-Else etc.

Info

Insbesondere wenn man ein AXSUtility mehrfach im Testfall benutzt, muss man das durch GetReportInfos zurückgegebene Dict in einer Liste (oder Deque) halten. Hintergrund ist, dass z.B. bei zweifacher Verwendung eines AXSUtility zunächst zweimal die Methode OnRun aufgerufen wird, bevor ein Aufruf von GetReportInfos erfolgt. Hält man die ReportInfos hingegen nur direkt in einem Dict, so wird dieses beim zweiten Aufruf von OnRun überschrieben. Der anschließende zweimalige Aufruf von GetReportInfos liefert dann immer das Dict der zweiten Ausführung des Utility. In den Beispielen (siehe Abschnitt Workspace Erstellung) demonstriert das Utility „LinspaceExample“ die korrekte Verwendung von GetReportInfos.

Nach dem Schließen des Utility Wizards kann das AXSUtility als Testschritt eingefügt und ausgeführt werden:

../_images/AXSUtility_3.png

Im Report erkennt man ein Utility, welches auf sich selbst gemappt ist (also das Interface und die Implementierung bereitstellt) an der Aktion „UTILITY -> UTL“:

../_images/AXSUtility_2.png

UserUtility

Der konkrete Aufbau eines Userutilities ist in der Dokumentation zur UserUtility API erläutert. Werden Userutilities aktualisiert und über den Menüeintrag „Benutzerbibliotheken aktualisieren“ (Shortcut Ctrl+Shift+R) neu geladen, dann müssen geöffnete Packages die diese Utilities verwenden geschlossen und neu geöffnet werden, damit die Aktualisierung wirksam wird.