Beliebte Suchanfragen
//

Mule 4: Test-Parametrisierung – ein Flow für viele Fälle

16.2.2023 | 5 Minuten Lesezeit

Immer wieder entdecke ich bei Code-Reviews, dass für verschiedene Testfälle, die sich prinzipiell nur durch die Ein- und Ausgabedaten unterscheiden, eine Vielzahl von MUnit-Tests angelegt werden. Diese Flows werden dann mühselig kopiert, um jeden Testfall abzudecken und es entsteht nach und nach ein in meinen Augen unübersichtliches Potpourri an Tests.

Nehmen wir zum Beispiel einmal an, ich habe einen simplen – sehr theoretischen – Use Case, bei dem man anhand einer Kategorie („ERNEUERBAR“, „NICHT ERNEUERBAR“) und eines Typs („WIND“, „SOLAR“, „KERN“, „ERDGAS“) den aktuellen Anteil an der Energieerzeugung in Prozent als Ergebnis bekommt. Im Fall, dass eine Kategorie oder ein Typ nicht erkannt wird, soll ebenfalls eine entsprechenede Nachricht angezeigt werden.

Prinzipiell wären das dann – mindestens – sieben verschiedene MUnit-Flows, die sich bis auf die Daten für Ein- und Ausgabe nicht unterscheiden. In der Realität existieren natürlich noch viele weitere Fälle, die ich hier außen vor gelassen habe.

Im schlechtesten Fall stellt man, nachdem man die Flows mühselig erstellt hat, fest, dass man etwas vergessen oder sich die Anforderung verändert hat – und schon beginnt man mit dem Umbau jedes einzelnen Flows.

Wäre es nicht schön, wenn man sich diese Arbeit sparen und gleichzeitig die Lesbarkeit erhöhen könnte?

Genau für diese Fälle gibt es eine charmante Lösung – die leider scheinbar oft unbekannte Test-Parametrisierung für MUnit-Tests. Diese möchte ich im Folgenden kurz und bündig vorstellen.

Test-Parametrisierung

Mit der Test-Parametrisierung bietet sich in Mule 4 die Möglichkeit, einen geschriebenen MUnit-Test mit verschiedenen Daten aufzurufen. Jeder Aufruf mit neuen Daten wird dabei wie ein neuer Testfall behandelt, sodass bei der Ausgabe – wie gewohnt – leicht ersichtlich ist, welcher Testfall erfolgreich bzw. mit welchem Fehler fehlgeschlagen ist. Das ergibt – wie ich bereits habe durscheinen lassen – besonders dann Sinn, wenn sich die Testfälle bis auf Ein- und Ausgabedaten nicht oder zumindest nicht essenziell unterscheiden.

Diese Parameter können entweder im XML der MUnit-Testdatei oder – wie ich es präferiere – über eine externe YAML-Datei, in der die Daten für alle Testfälle übersichtlich eingepflegt und problemlos erweitert werden können, definiert werden. 

Im weiteren Verlauf werde ich für das Beispiel nur auf die YAML-basierte Testerstellung eingehen. Wenn man diese nachvollzogen hat, kann man die XML-basierte Variante in der Dokumentation jedoch auch leicht nachvollziehen.

Sollte YAML für euch neu sein oder es euer Interesse geweckt haben, verweise ich auf die offizielle YAML-Spezifikation.

Das Beispiel

In meinem in der Einleitung skizzierten Beispiel haben wir also einen Business-Flow, der anhand einer Kateogie und eines Typs den Anteil an der Energieerzeugung ausgibt.

Der Beispielflow


Dieses Beispiel ist natürlich sehr simpel gehalten, sollte aber ausreichen, um zu zeigen, wie die Parametrisierung genutzt werden kann. (Dieses Beispiel ist natürlich sehr einfach und vor allem fiktiv! Bitte nagelt mich nicht auf unter Umständen realitätsferne Werte fest!)

⁠Die YAML-Datei

Wenn ich weiß, dass die Parametrisierung für meinen Fall sinnvoll ist, beginne ich üblicherweise mit der Erstellung der YAML-Datei im test/resources-Ordner. In meinem Fall erstelle ich dort eine Datei mit dem Namen energie_test_parameterization.yaml. In der Datei vergebe ich für den ersten Test den Titel „erneuerbar-solar-test“ und die drei benötigten Parameter – eingerückt – kategorie, typ und expectedText. Der Name wird später bei der Ausführung des Tests zur Identifikation des Testfalls genutzt.

Das Ganze sieht zu diesem Zeitpunkt wie folgt aus:

erneuerbar-solar-test:
    kategorie: "ERNEUERBAR"
    typ: "SOLAR"
    expectedText: "11.7%"


Für den Anfang pflege ich dabei nur einen Datensatz ein. Dies bietet mir den Vorteil, dass ich, wenn ich etwas vergessen habe, direkt beim Erstellen des MUnit-Testcases noch frühzeitig Anpassungen vornehmen kann. Das kann man natürlich wie es einem beliebt handhaben.

MUnit-Test

Nun kann, wenn noch nicht geschehen, die MUnit-Test-Datei wie gewohnt angelegt werden. Im Vergleich zu sonst ist es aber wichtig, dass wir der MUnit-Datei den Namen unserer YAML-Datei bekanntmachen. Dies geschieht über den munit:config-Tag.

<munit:config name="energieverteilung-test-suite.xml">
       <munit:parameterizations file="energie_test_parameterization.yaml" />
</munit:config>

Dann kann man wie gewohnt seinen Test-Flow erstellen:

Der Test Flow

Der große Unterschied ist hierbei, dass wir in unseren Processors nun unsere in der YAML-Datei festgelegten Properties angeben können. So setzen wir im „Set Event“-Processor folgenden Payload:

#[{
	kategorie: p('kategorie'),
	typ: p('typ')
}]

An dieser Stelle hätte ich auch direkt das Objekt in der YAML-Datei hinterlegen können, sodass ich mir dieses nicht erst hätte zusammenbauen müssen.

Gleichermaßen verhält es sich mit dem „Assert equals“-Processor. Dieser bekommt als zu vergleichenden Parameter ${expectedText} übergeben.

Der Assert Equals Processor


Das war es auch schon. Nun kann der erste Testlauf gestartet werden! Und wenn alles funktioniert hat, sollte das Resultat wie folgend aussehen:

Wie versprochen können wir weitere Testfälle nun bequem über die YAML-Datei hinzufügen. Die erweiterte YAML-Datei sieht in unserem Fall dann so aus:

erneuerbar-solar-test:
    kategorie: "ERNEUERBAR"
    typ: "SOLAR"
    expectedText: "11.7%"

erneuerbar-wind-test:
    kategorie: "ERNEUERBAR"
    typ: "WIND"
    expectedText: "25.1%"

erneuerbar-unbekannt-test:
    kategorie: "ERNEUERBAR"
    typ: "UNBEKANNT"
    expectedText: "Typ UNBEKANNT für Kategorie ERNEUERBAR unbekannt"
    
nicht-erneuerbar-erdgas-test:
    kategorie: "NICHT-ERNEUERBAR"
    typ: "ERDGAS"
    expectedText: "9.5%"

nicht-erneuerbar-kern-test:
    kategorie: "NICHT-ERNEUERBAR"
    typ: "KERN"
    expectedText: "6.7%"

nicht-erneuerbar-unbekannt-test:
    kategorie: "NICHT-ERNEUERBAR"
    typ: "UNBEKANNT"
    expectedText: "Typ UNBEKANNT für Kategorie NICHT-ERNEUERBAR unbekannt"
    
unbekannt-kategorie-test:
    kategorie: "UNBEKANNT"
    typ: "UNBEKANNT"
    expectedText: "Kategorie UNBEKANNT unbekannt"



Und schon können wir unseren Testfall erneut laufen lassen – und erhalten folgendes Ergebnis:

Alle Testfälle

Beim Betrachten unseres Business-Flows sehen wir anhand des Häkchens, dass wir mithilfe der definierten Tests nun jeden Zweig einmal durchlaufen haben.

Der BusinessFlow mit Häkchen

Fazit

Die Parametrisierung für MUnit-Tests ist eine sehr elegante Lösung, wenn man viele – wie in meinem konstruierten Fall – gleichartige Testszenarien hat. Gleiches gilt auch für Flows, die Berechnungen durchführen und für die man Ein- und Ausgabe deterministisch bestimmen kann. So könnte auf diese Art und Weise sogar ein technisch Fremder eine von uns als Entwickler erstellte Datei leicht mit zu testenden Daten anreichern und erweitern.

Natürlich ist die Parametrisierung nicht immer sinnvoll oder erzeugt unter Umständen sogar Mehrarbeit. Dies muss man jedoch von Fall zu Fall abwägen.

Ich bedanke mich für euer Interesse und freue mich über Kritik und Rückfragen.

Beitrag teilen

//

Weitere Artikel in diesem Themenbereich

Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.

//

Gemeinsam bessere Projekte umsetzen.

Wir helfen deinem Unternehmen.

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.