Tutorial Schlüsselwortbasiertes Testen

Dieses Tutorial gibt einen Überblick über die Möglichkeiten des schlüsselwortbasierten Testens, die ecu.test bietet.

Die im Tutorial verwendeten Beispieldaten werden mit ecu.test ausgeliefert. Wie die Beispieldaten in einen Workspace eingebunden werden können, ist hier beschrieben. Zu finden sind die Dateien für dieses Tutorial im Unterordner Tutorial-KeywordBasedTesting.

Die folgenden zwei Ansätze ermöglichen ein schlüsselwortbasiertes Testen:

  1. Sprechende Namen der Bibliothekspackages in Testfällen

  2. Evaluierung der Rückgabewerte von Bibliothekspackages

Grundlagen des schlüsselwortbasierten Testens

Eines der Kernfeatures in ecu.test ist die Verwendung von Packagereferenzen, d. h. Packages können andere Packages aufrufen. Dies ermöglicht die Kapselung von speziellen Testabläufen, die in zahlreichen Testfällen wiederverwendet werden können. Mehrere solcher Hilfspackages können zu Bibliotheken zusammengefasst werden, was die Wartbarkeit erhöht und für eine saubere Strukturierung von Testfällen sorgt.

Info

Abzugrenzen ist dieses Konzept von den Bibliotheksworkspaces. Die Packages der hier gemeinten Bibliotheken liegen im selben Workspace.

Das schlüsselwortbasierte Testen setzt auf den Bibliothekspackages auf. Mit Hilfe von Schlüsselwörtern können Testfälle spezifiziert werden, die universell austauschbar sind, da alle dieselbe Sprache verwenden. Jedes Schlüsselwort beschreibt dabei eine Eingabegröße (Parameter oder Signale). Das Schlüsselwort bildet damit eine Schnittstelle zwischen der Testfallspezifikation und der Implementierung.

Das schlüsselwortbasierte Testen kann in ecu.test im Rahmen von Packagereferenzen und mithilfe von Mappinggrößen realisiert werden.

Alternative Anzeigenamen

ecu.test bietet die Möglichkeit, im Mapping einer Packagereferenz einen alternativen Anzeigenamen zu vergeben, welcher Platzhalter verwenden kann. Es gibt zwei Arten von möglichen Platzhaltern:

  • Parameter: Mit ${Parameter.MY_PARAM} kann auf die Werte der Parameter des referenzierten Packages zugegriffen werden.

  • Mappings: Mit ${Mapping.MY_SIGNAL} kann auf die Namen der Mappings des referenzierten Packages zugegriffen werden.

Mithilfe der Parameter und Mappings können Packages generisch geschrieben und mit verschiedenen Signalen und Parametern aufgerufen werden. Damit die Platzhalter im Aufruf-Namen korrekt aufgelöst werden, müssen alle referenzierten Größen im Package-Aufruf korrekt parametriert werden. Der Name des Testschritts entspricht anschließend dem Schema <Name des Mappings>: <Alternativer Anzeigename>, wobei die Platzhalter durch die parametrierten Werte ersetzt sind. Nicht auflösbare Platzhalter führen zu keiner Fehlermeldung, werden jedoch auch nicht ersetzt.

Ein Tutorial zum Thema alternative Anzeigename ist unter Tutorial Schlüsselwortbasiertes Testen zu finden.

Package-Rückgabewerte

Für die Rückgabewerte einer Packagereferenz können Erwartungen definiert werden. Diese werden dann im aufrufenden Package evaluiert. Entsprechen alle Rückgabewerte ihren Erwartungswerten, ist das Ergebnis SUCCESS. Entspricht mindestens ein Rückgabewert nicht den Erwartungen, wird das Bibliothekspackage als FAILED bewertet.

Die Bewertung der Rückgabewerte kann auch an zeitliche Bedingungen geknüpft werden.

Sprechende Packageaufrufe

Motivation

Als Tester möchte ich eine Bibliothek generischer Testabläufe erstellen, die ich flexibel in meinen Testfällen wiederverwenden kann. Außerdem möchte ich, dass die Testschritte von der Formulierung her möglichst nah an meiner Spezifikation liegen.

Generisches Referenzpackage erstellen

Zunächst erstelle ich mein Bibliothekspackage StartStopEngine.pkg, welches meinen Motor startet bzw. stoppt und den Erfolg anhand eines von mir gewählten Signals prüft. Ich möchte dabei flexibel angeben können, ob ich starten oder stoppen will und mithilfe von welchem Signal ich den Erfolg überprüfe. Dazu lege ich im Package einen Parameter EngineRequest vom Typ Enum mit den Werten ‚Start‘ und ‚Stop‘ an:

../_images/StartStopEngine_EngineRequest.png

Für das Lesen eines beliebigen Signals füge ich einen generischen Lesen-Testschritt mit dem Mapping-Namen QuantityToCheck ein. Als Bewertung gebe ich an, dass der Messwert entweder größer 0 (beim Starten) oder gleich 0 (beim Stoppen) sein soll:

../_images/StartStopEngine_QuantityToCheck.png

Referenzpackage mit sprechendem Namen verwenden

Anschließend möchte ich mein Referenzpackage StartStopEngine.pkg in einem Testfall Testpackage.pkg verwenden. Beim ersten Aufruf soll der Motor gestartet und der erfolgreiche Start anhand des Signals VehicleSpeed geprüft werden. Beim zweiten Aufruf soll der Motor gestoppt und der Erfolg mithilfe von EngineSpeed überprüft werden. Außerdem möchte ich beide Packageaufrufe besser voneinander unterscheiden zu können und bereits anhand des Anzeigenamens erkennen, wie mein Bibliothekspackage parametriert ist.

Um das zu erreichen, benötige ich einen Mapping-Eintrag für mein Bibliothekspackage StartStopEngine.pkg. Das ist sowohl im Globalen Mapping als auch im Lokalen Mapping des aufrufenden Packages (hier: Testpackage.pkg) möglich.

Für dieses Tutorial erstelle ich einen Eintrag im globalen Mapping. Im Bearbeitungsdialog des Mappings kann ich einen Alternativen Anzeigenamen vergeben. In diesem alternativen Anzeigenamen kann auf Werte der Parameter und Mappings des referenzierten Packages zugegriffen werden. Die benötigte Notation dafür ist ${Parameter.Mein_Parameter} für Parameter und ${Mapping.Mein_Mapping_Eintrag} für Mappings:

../_images/EditMappingItem_AltCallRepr.png

Im Mapping-Eintrag für StartStopEngine.pkg referenziere ich EngineRequest mit ${Parameter.EngineRequest} und QuantityToCheck mit ${Mapping.QuantityToCheck}. Deren Werte werden ersetzt, sobald ich den Mapping-Eintrag in Testpackage.pkg gezogen und den Package-Aufruf parametriert habe.

Als nächstes ziehe ich den Mapping-Eintrag also zweimal in Testpackage.pkg und parametriere die Aufrufe wie gewünscht:

../_images/TestPackage.png

Der Anzeigetext meines Referenzpackages StartStopEngine.pkg in Testpackage.pkg enthält nun auch den alternativen Text mit den parametrierten Werten und ich kann auf einen Blick sehen, was meine Package-Aufrufe tun werden.

Evaluierung der Rückgabewerte von Bibliothekspackages

Motivation

Als Tester möchte ich eine Bibliothek generischer Testabläufe erstellen, die ich flexibel in meinen Testfällen wiederverwenden kann. Ein Teil der Bibliothekspackages generiert dabei intern Rückgabewerte. Diese möchte ich direkt im Packageaufruf bewerten.

Referenzpackage mit Rückgabewerten erstellen

Ich nutze das Package StartStopEngine.pkg aus dem Tutorial zu den Sprechenden Packageaufrufen als Vorlage. Dieses Package startet bzw. stoppt ein Motoren-Modell und prüft den Erfolg des Starts/Stops mithilfe eines von mir gewählten Signals. Statt das Ergebnis des Lesens meiner generischen Größe jedoch direkt in meinem Package zu bewerten, speichere ich es als Rückgabewert QuantityToCheckResult:

../_images/StartStopEngineWithReturnValue.png

Bewertung des Rückgabewertes

Anschließend erstelle ich ein neues Package TestPackageWithReturnValueEvaluation.pkg, in welchem ich StartStopEngineWithReturnValue.pkg aufrufe. Ich parametriere den Aufruf so, dass mein Motoren-Modell gestartet und anhand der Größe EngineSpeed geprüft wird, ob das Starten erfolgreich war. Da ich einen Rückgabeparameter angegeben habe, wird mir dieser im Tab Parametrierung des Package-Parametrierung-Dialogs angezeigt. Dort kann ich auch meine Erwartung angeben und setze sie auf „>0“:

../_images/DefineReturnValueExpectation.png

Wenn ich TestPackageWithReturnValueEvaluation.pkg ausführe, erhält der Aufruf von StartStopEngineWithReturnValue.pkg eine Bewertung entsprechend meiner definierten Erwartung und ich kann alle nötigen Informationen auf einen Blick einsehen:

../_images/ReturnValueEvaluation_TestReport.png

Verwendung von Zeitoptionen zur Bewertung des Rückgabewertes

Die Bewertung des Rückgabewertes kann auch an zeitliche Bedingungen geknüpft werden. Dazu klappe ich nach dem Setzen des Erwartungswerts das Panel Zeitoptionen aus. Mit der Option Warte bis wahr lege ich fest, dass das erwartete Ergebnis innerhalb einer gewissen Zeit eingetreten sein muss. Ich setze die Zeitüberschreitung auf 10 Sekunden und den Polling-Zyklus auf 500ms, wodurch das Package alle 500ms ausgeführt wird, bis entweder alle Erwartungen erfüllt wurden (Erfolgsfall) oder nicht alle Erwartungen erfüllt sind und die maximale Ausführungszeit von 10 Sekunden erreicht wurde (Fehlerfall).

../_images/DefineReturnValueExpectationWithTimeOptions.png

Durch das Setzen der Zeitoptionen erhalte ich zusätzliche Informationen zur verwendeten Zeitoption und der Anzahl der Durchläufe in den Details der Testergebnisse.

../_images/ReturnValueEvaluationWithTimeOptions_TestReport.png

Eine detaillierte Beschreibung aller Zeitoptionen findet sich im Kapitel Zeitoptionen.