Beliebte Suchanfragen
|
//

Testen von Mule ESB Applikationen (Teil 1/3): Modultests und funktionales Testen

19.1.2015 | 6 Minuten Lesezeit

Abstrakt

Im allgemeinen Konsens wird das Testen von Software als integraler Bestandteil des Software Entwicklungsprozesses gesehen. Tests sollten in allen Phasen der Softwareentwicklung eingesetzt werden: von Unit- bis zu Akzeptanztests. Vor allem im Software Engineering bilden zusammenhängende und automatisierte Tests ein Sicherheitsnetz gegen regressive und inkompatible Änderungen.

In Integrationsprojekten mit Mule ESB sind diese Aspekte auch von Belang. Komponenten in Mule-Flows, die Flows selber und deren Integration müssen intensiv getestet werden.

Dieser Artikel ist der erste Teil einer Serie zum Thema des Testens von Mule ESB Projekten auf allen Ebenen. Der Fokus dieses Artikels liegt auf Modul- und funktionalen Tests, die die kleinsten Komponenten in einem Mule Projekt testen.

Testen von Software – Die Test Pyramide

Bevor wir tiefer in das Thema eintauchen, werfen wir einen Blick auf den Kontext des Testens selber. Idealerweise wird in Software Projekten von unten aufwärts getestet. Zuerst mit einer großen Basis an Testfällen, die, idealerweise automatisch bei jedem Build, durch Unit- und Modultests die kleinsten Komponenten testen. Auf dem Weg durch die Architektur nimmt die Anzahl an Testfällen ab, da die nun größeren Komponenten Kompositionen aus den bereits getesteten Komponenten sind. Dies geschieht bis man die Spitze der Pyramide erreicht, wo die Applikation als Einheit durch manuelle Überwachung von Tests oder manuelles Testen geprüft wird. [1 ]

Source: http://watirmelon.com/2012/01/31/introducing-the-software-testing-ice-cream-cone/
Automatisierte Test Pyramide

Modultests

Auf der untersten Ebene verifizieren Unit- und Modultests die korrekte Funktionalität von Klassen. Diese Klassen können bei Mule Projekten einfach Erweiterungen und Anpassungen des Mule Frameworks sein. Beispiele sind:

  • Individualisierte Transformer
  • Individualisierte Komponenten
  • Individualisierte Evaluationen von Ausdrücken
  • Und generell alle Spring Beans die eine Mule Applikation nutzen soll. Typischerweise sind solche Beans in einem Mule-Module-Projekt Teil einer Bibliothek und werden deswegen separat beim Bauen der Bibliothek getestet.

Unit Tests im klassischen Sinne testen die Funktionalität von einzelnen Klassen, ohne Mule ausführen zu müssen. Eine einfache Java Klasse (POJO) und ihr Testfall am Beispiel einer Kunden Transformationslogik könnten so aussehen:

1public class CustomerTransformationComponent {
2 
3   public Map<String, Object> tranformCustomer(Customer customer) {
4      Map<String, Object> returnMap = Maps.newHashMap();
5      returnMap.put("name", customer.getName());
6      // Fields mapping
7      // ...
8      return returnMap;
9   }
10}
11 
12public class CustomerTranformationComponentTest {
13 
14   @Test
15   public testTransform() {
16      Customer testCustomer = new Customer();
17      // Create test data
18      Map<String, Object> customerMap = new CustomerTransformationComponent()
19            .tranformCustomer(testCustomer);
20      // Assert test data
21   }
22}

Das Test Compability Kit (TCK)  des Mule Frameworks stellt für das Testen von Erweiterungen und Anpassungen einen Mule-Kontext bereit [3 ]. Zu jedem Mule-Komponententyp gibt es zu diesem Zweck eine abstrakte Elternklasse, welche von org.mule.tck.junit4.AbstractMuleTestCase abgeleitet ist. Diese sind in der Bibliothek mule-core-3.5.2-tests.jar für Mule in der Version 3.5.2 untergebracht.

Eine Java-Komponente, die das Mule-Interface Callable implementiert,  mit einer komplexeren Logik, die auf den Mule Kontext angewiesen ist, kann mit der entsprechenden Klasse SimpleJavaComponentTestCase getestet werden:

1public class CustomerComponent implements Callable {
2 
3   @Autowired
4   public CustomerService service;
5 
6   @Overwrite
7   public Object onCall(MuleEventContext eventContext) throws Exception {
8      String customerId = (String) eventContext.getMessage().getPayload();
9 
10      Customer customer = service.getCustomer(customerId);
11 
12      Map<String, Object> customerDetails = transformCustomer(customer);
13 
14      return customerDetails;
15   }
16}
17 
18public class CustomerComponentTest extends SimpleJavaComponentTestCase {
19 
20   @Test
21   public testOnCall() {
22      // Create test data
23      MuleEvent event = getTestEvent(payload, muleContext);
24      new CustomerComponent().onCall(new DefaultMuleEventContext(event));
25      // Assert test data
26   }
27}

Folgende Vorteile bringen solche Unit Tests:

  • Komponenten, die mit den TCK Testfällen getestet werden, stellen sicher, dass das Verhalten der Komponente mit dem Mule Framework kompatibel ist.
  • Das Verwenden von TCK Testfällen erlaubt es Entwicklern, sich auf das Schreiben von Test für spezifisches Verhalten ihrer Komponenten zu konzentrieren.
  • Für den Fall, dass eine Methode in der Komponenten API nicht vom TCK Test Fall getestet wird, stellt der Testfall eine abstrakte Methode für den Test zu Verfügung. Dadurch kann der Entwickler Tests für alle Bereiche der Komponente schreiben.
  • Das TCK stellt ein Standard Testmodell zur Verfügung, welches aus einfachen Testklassen besteht. Der Entwickler muss für seine Testfälle nicht immer wieder neue Testklassen schreiben, sondern kann die Klassen aus dem TCK verwenden, um Standardfunktionalität zu testen. Z.B. wird der Mule Lebenszyklus der Komponente automatisch mit getestet.

Funktionales Testen von Mule Komponenten

Wenn es um das Testen der Interaktion und der Komposition zwischen Komponenten in Teil Flows oder „einfacheren“ Flows geht, werden funktionale Tests empfohlen [4 ]. Da Mule ESB leichtgewichtig und in Tests leicht integrierbar ist, wird die org.mule.tck.junit4.FunctionalTestCase Klasse des TCK empfohlen, um Teile von oder ganze Flows zu testen. Wenn man einen Unit-Test mit dieser Klasse erstellt, enthält diese automatisch eine integrierte Mule-Instanz mit einem Mule-Kontext, um funktionale Tests der Mule Flows durchzuführen.

Ein Schwerpunkt dieser Tests sind die folgenden Aspekte:

  • Funktionalität der Nachrichten Flows
  • Nachrichten Validation und Regel basiertes Routing in den Flows
  • Und deren Fehler Behandlung

Ein Beispiel Teil Flow welcher getestet werden sollte, könnte so aussehen

1<sub-flow name="subFlow" doc:name="subFlow">	 	 
2 <component class="de.codecentric.example.CustomerComponent" doc:name="Java"/>	 	 
3</sub-flow>

Um diesen Teil Flow ausführen zu können, kann man den Aufruf des Flows mit einem VM Endpoint durchführen, der in einer Test Ressourcen XML Datei definiert wird:

1<flow name="TestFlow" doc:name="TestFlow">	 	 
2 <vm:inbound-endpoint exchange-pattern="request-response" path="TestFlow" doc:name="VM endpoint"/>	 	 
3 <flow-ref name="subFlow" doc:name="Call sub flow for testing"/>	 	 
4</flow>

Der passende Unit Test könnte wie folgt aussehen:

1public class SubFlowTest extends FunctionalTestCase {
2 
3   @Test
4   public void testFlow() throws Exception{
5      MuleClient client = muleContext.getClient();
6      String inputPayload = "550e8400-e29b-11d4-a716-446655440000";
7      // Create test data
8      MuleMessage reply = client.send("vm://TestFlow", inputPayload, null, 5000);
9 
10      assertNotNull(reply);
11      assertNotNull(reply.getPayload());
12      // Assert test data
13   }
14 
15    @Override
16    protected String[] getConfigFiles() {
17        return new String[]{"./src/test/app/sub-flow-test.xml", 
18            "./src/main/app/sub-flow.xml"};
19    }
20}

Das Überschreiben der getConfigFiles() Methode stellt dem Testfall die benötigten Mule- und Spring-Konfigurationsdateien zur Verfügung. Wir empfehlen dabei, die Produktions XML-Beschreibung und die Test-XML-Konfiguration in separaten XML-Dateien testspezifisch unter zu bringen.

Dieses einfache Beispiel kann ohne das Mocken oder das interne Anpassen von Flows getestet werden. Mule stellt eine Möglichkeit zur Verfügung, mittels  Komponenten zu einem Flow hinzuzufügen, welche Mocking und Test-Funktionalität bereitstellen. Dies hat leider den Nachteil, dass die Flow-Beschreibung mit Testinformationen gemischt wird. Wir empfehlen für solche Fälle die Bibliothek MUnit, welche im nächsten Blog Artikel beschrieben wird.

Das Testen der (Teil-)Flows mit einer integrierten Mule-Instanz und mit einer sauberen Trennung der Flow-Beschreibung zwischen Test und Produktion birgt folgende Vorteile:

  • Die Konfiguration und die Flows können isoliert von einander getestet werden, welches eine saubere Separation der Tests und eine Reduktion der Größe der Testfälle bewirkt. Fehler können auf diese Weise gezielter identifiziert werden, da sie explizit in Testfällen lokalisiert werden können.
  • Es ist nicht gewünscht Mule-Standardkomponenten zu testen, da man davon ausgehen kann, das diese bereits ausführlich getestet worden sind. Deswegen sollten nur die Pfade und Komponenten eines Flows getestet werden, die vom Entwickler erstellt worden sind.
  • Testfälle benötigen ihre eigene Test-Infrastruktur, welche idealerweise aus In-Memory Infrastruktur-Komponenten besteht (z.B. VM als Transport, ActiveMQ für JMS oder H2 als Datenbank). Dies ist notwendig, da die Produktionsumgebung nicht immer automatisiert oder integriert in Unit-Tests aus Lizenz-, Ressourcen- oder Performanzgründen bereitgestellt werden kann.
  • Erhöhte Wiederverwendung zwischen Tests, z.B. von der In-Memory Infrastruktur, kann erreicht werden durch einmalige Bereitstellung der Konfiguration für alle Testfälle.

Fazit

Wir haben in diesem Blog Artikel eine Einführung in die ersten Schritte des Testens von Mule-Applikationen gegeben. Zunächst haben wir beschrieben, wie auf der niedrigsten Schicht Komponenten und (Teil-)Flows einer Mule-Applikation getestet werden können und welche Vorteile dies bringt. Wir haben zu diesem Zweck klassische Unit-Tests mit JUnit, mit Mule-Kontext mit dem TCK-Framework und funktionale Tests des TCK vorgestellt. Diese Tests können in Mule-Applikation, die nur aus einem Modul bestehen, oder in Bibliotheken, welche Komponenten und Teil-Flows für Multi-Modul Mule-Applikationen enthalten, angewendet werden.

Serie

Dieser Artikel ist Teil einer Mule ESB Serie zum Thema Testen von Mule Applikationen:

Referenzen

[ 1] http://martinfowler.com/bliki/TestPyramid.html
[ 2] http://watirmelon.com/2012/01/31/introducing-the-software-testing-ice-cream-cone/
[
3] http://www.mulesoft.org/documentation/display/current/Unit+Testing
[ 4] http://www.mulesoft.org/documentation/display/current/Functional+Testing

|

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.