Hilfe bei Integrationstests
IT-Spezialisten ist es vollkommen klar, dass das Testing von IT-Systemen wichtig ist. Wir können und müssen damit leben, dass wir genauso viele (wenn nicht mehr) Ressourcen ins Testing investieren wie in die Umsetzung von funktionalen und nicht funktionalen Anforderungen. Wir sind alle damit einverstanden, dass effektive Tests und eine gute Testabdeckung die Voraussetzung für gute Code- und Produktqualität sind. Außerdem ist Refactoring ohne ausreichende Tests schwer vorstellbar.
Es gibt verschiedene Teststufen: Unit-Tests, Integrationstests, Systemtests, Abnahmetests. In den zwei ersten Phasen sind die Produktentwickler stark involviert. Für Unit-Tests existieren Frameworks wie JUnit 4/5, Mocki- to oder AssertJ [1]. Mit diesen Tools lassen sich kurze und elegante Tests schnell erstellen. Die Frameworks sind gut dokumentiert und einfach zu erlernen. Wenn es sich um Integrationstests handelt, ist es allerdings nicht mehr ganz so einfach. Mithilfe von Integrationstests wollen wir überprüfen, ob das System ein korrektes Verhalten zeigt, wenn es auf dem Applikationsserver läuft und in verschiedene Umsysteme und Datenbanken eingebunden ist. Das funktioniert, wenn wir beispielsweise eine öffentliche Schnittstelle (REST/SOAP) testen wollen. In diesem Fall generieren wir einen Java-Client, schicken eine Anfrage an das System und kontrollieren, ob das System die erwartete Antwort zurückliefert. Durch Datenbanktools (etwa DbUnit) kann man feststellen, ob der Datenbankstand nach dem Serveraufruf korrekt ist.
Aber wie kann man interne Services testen, die keine Webschnittstelle zur Verfügung stellen? Hier meinen wir nicht die Unit-Tests, die wir alle kennen. Wie testen wir so einen internen Service auf dem Applikationsserver, wenn er auf andere Systeme und Datenbanken zugreift? Könnten Mocks dabei behilflich sein? Das Mocken von externen Aufrufen (insbesondere bei JPA) ist sehr aufwendig und in manchen Fällen sinnlos, denn letztendlich ist dann alles gemockt und es bleibt nichts zum Testen.
Welche Frameworks stehen zur Verfügung? Es gibt Arquillian, aber das hat in manchen Situationen Nachteile, die das Testen etwas schwieriger machen. Wenn das System groß ist oder aus mehreren Subsystemen besteht, kann der Zusammenbau des Deployments eine Herausforderung sein. Daneben macht es ein neues Deployment für jede Testklasse. Wenn es um Hunderte von Testklassen geht und das Deployment relativ lange dauert, ist das nicht mehr effizient.
Man könnte argumentieren, dass solche großen Deployments ohnehin Vergangenheit seien und alles auf Microservices umgestellt werden solle. Wir wissen jedoch, dass das aus verschiedensten Gründen nicht immer möglich ist. Auch gibt es bestehende Applikationen, die man warten und weiterentwickeln muss. Was könnte man einsetzen, wenn man Tests gegen eine bereits installierte Applikation ausführen will? Für eines unserer Projekte suchten wir ein solches Tool und haben WarpUnit [2] gefunden.