Testen von Enterprise Java Beans 3.1

Inhaltsverzeichnis

Einleitung

Das Testen der vorherigen EJB Version (2.x) konnte oftmals nur mit großem Aufwand durchgeführt werden. Dies lag unter anderem an der engen Verzahnung der Komponenten mit der vorhandenen Infrastruktur. Auch die lang andauernden Build- und Deploy-Zyklen erschwerten das Testen von EJBs innerhalb eines Applikation-Servers. Ein Testen außerhalb des Servers war zudem sehr stark begrenzt. Dies ist unter anderem darin begründet, dass die Java Beans der zweiten Generation bei der Implementierung eine Menge an Serverdiensten wie beispielsweise den Namensdienst benötigen.

Durch die EJB Version 3 wurden zahlreiche Verbesserung an der generellen Struktur vorgenommen, sodass auch das Testen von EJBs stark vereinfach wurde. Eine entscheidende Änderung ist die Rückkehr zum einfach POJO, wodurch die EJBs keine technischen Schnittstellen mehr implementieren müssen und dadurch aufwändige Komponentenschnittstellen und die Implementierung von EJB-Schnittstellen entfallen. Neben der Möglichkeit der Vererbung können die EJBs aufgrund des Wegfalls infrastrukturellen Quellcodes bei der Implementierung über den new()-Operator erstellt werden. Auch die Anzahl notwendiger Artefakte wurde signifikant verringert. Waren bei einer SessionBean in der Version 2.x noch Artefakte wie der Deployment Descriptor, das Home- sowie das Component-Interface vonnöten, so wird in der Version 3.x lediglich ein Interface (POJI) und die Bean (POJO) als solche benötigt. Eine weitere wesentliche Änderung ist die Möglichkeit, beispielsweise Ressourcen mittels Dependency Injection (DI) injizieren zu können. Diesen - und einigen weiteren - Ansätzen ist es zu verdanken, dass die allgemeine Testbarkeit von EJBs enorm gesteigert werden konnte. Durch die vereinfachte Programmierung und die Nutzung von DI können EJBs relativ einfach aus der Anwendung herausgelöst und beispielsweise mittels JUnit auch außerhalb des Applikationsservers getestet werden.

Mit der EJB Version 3.1 folgte eine weitere Änderung der Java EE Komponenten, die als "embedded Usage" bezeichnet wird. Dieser Ansatz beschreibt die Möglichkeit, EJBs auch ohne Applikation-Server in einem lokalen Container innerhalb derselben virtuellen Maschine, auf der auch der Client läuft, auszuführen. Da nur eine JVM verwendet wird, können die EJB über JNDI aufgefunden und getestet werden.

Für EJB-Komponenten existieren verschiedene Ebenen von Tests. Innerhalb dieses Dokuments werden ausschließlich Unit-Tests beschrieben, die gleichzeitig das Fundament für weitere Testszenarien legen. Akzeptanz-, Last- oder Integrationstests sollen an dieser Stelle nicht behandelt werden. Für Unit-Tests im Bereich der Enterprise-Beans existieren verschiedene Möglichkeiten, die in drei Kategorien unterteilt werden können:

Im Folgenden wird auf die verschiedenen Varianten eingegangen und die Grenzen der einzelnen Tests aufgezeigt sowie unterstützende Programme vorgestellt.

Testen mittels einfachen Plain Old Java Tests (POJT)

Der erste Grundsatz beim Testen sollte stets sein, so viel wie möglich außerhalb des Containers zu testen. Dies liegt darin begründet, dass die zuvor implementierte Geschäftslogik getestet werden soll und nicht die Plattform, auf welche diese Geschäftslogik läuft. Für das Unit-Testen außerhalb des Containers eigenen sich ins besondere die Testframeworks JUnit und TestNG (siehe [04], [05]). Einführende Beispiele für den Umgang mit den Testframeworks JUnit und TestNG sind ebenfalls auf den Seiten des Forschungsprojekts zu finden. Um sich beim Testen auf die zu testende Geschäftslogik zu beschränken, bietet sich der Einsatz von sogenannten Mock-Objekten an. Mock-Objekte sind stark vereinfachte, minimalistische Stellvertreter für die benötigten Fremdklassen und Fremdsysteme. Durch die Trennung zwischen Implementierung und Schnittstelle können Mock-Objekte die Schnittstelle der Fremdklasse bzw. des Fremdsystems implementieren, realisieren aber nur die für den Test erforderlichen Teil und diese meist auch so einfach wie möglich. Üblich sind statische, fest verdrahtete Antworten und Rückgabewerte. Für den Einsatz von Mock-Objekten bieten sich die Frameworks Mockito und Easymock an. Zudem erfüllt diese Art des Testens den häufigen Anspruch nach einer schnellen und direkt ausführbaren Lösung. Dies kann alleine schon mit der Tatsache begründet werden, dass keine Deployment auf einem Applikationsserver stattfindet. Allerdings sind die Grenzen des Testens mittels einfacher POJT schnell erreicht, wenn Funktionen oder Dienste der Umgebung, hier insbesondere die des Applikationsservers, genutzt werden. Sicherlich könnte der ein oder andere Dienst mittels Mock-Objekten nachempfunden werden. Dies entspricht jedoch nicht der Philosophie des einfachen Testens. EJBs lassen sich also mit vertretbarem Aufwand lokal ohne Applikationsserver testen, wenn sie:

An dieser Stelle kann festgehalten werden, dass ein Unit-Test von EJB mit den genannten Hilfsmitteln leicht zu realisieren ist. Werden von der EJB jedoch Dienste der Umgebung genutzt, sind die Mittel des Testens in diesem Fall schnell erschöpft und es muss dann auf ein Testen innerhalb eines Embedded Containers zurückgegriffen werden.

Testen innerhalb eines Embedded Containers

Wie anfänglich bereits beschrieben, wurde der EJB-Standard um die Möglichkeit erweitert den Betrieb von Java-Beans ohne Server umzusetzen. Dieser als "Embedded Usage" bezeichneter Ansatz wird durch einen lokalen Container möglich, in dem die EJBs bereitgestellt werden und welcher in derselben virtuellen Maschine wie der Client ausgeführt wird. Demnach werden weder ein Applikationsserver noch eine Remote-Kommunikation benötigt. Da EJBs aber mehr als nur POJOs sind und erst auf dem Applikationsserver ihr wirkliches Verhalten offen legen, reicht das im vorherigen Kapitel vorgestellte Testen der reinen Geschäftslogik nicht aus. Eine der wichtigsten Regeln beim Testen von EJBs ist das Testen des eigenen Quellcodes bzw. der Geschäftslogik und nicht die Plattform in Form des Applikationsservers. Die Gründe für ein Testen innerhalb des Embedded Containers sind recht plausibel. EJBs können wie bereits beschrieben beispielsweise auf den Kontext zugreifen oder auf den Einsatz von Interceptoren angewiesen sein. Dieses Zusammenspiel lässt sich nur zuverlässig auf einem Applikationsserver testen. Ein weiterer ebenso wichtiger Grund sind Fehler des Entwicklers, die bei der Verwendung der Funktionalität des Applikationsservers sowohl im logischen als auch im konzeptionellen Bereich auftreten können. Ein einfacher Unit-Test ohne eine Applikationsserver-Umgebung würde solche Fehler nicht aufdecken. Die Vorteile eines Embedded Containers liegt zum einen im wesentlich schnelleren Deployment und der schnelleren Kommunikation im Gegensatz zum umfangreichen Applikationsserver und zum anderen können die Java-Beans über JNDI gefunden und im Anschluss getestet werden. Das explizite Erstellen und Ausliefern von Java Archiven (JAR) entfällt ebenso, wie die Trennung zwischen Client und Server, wodurch das Testen erleichtert wird. OpenEJB (vgl. [08]) oder Cuba (vgl. [09]) sind Beispiele für einen Embedded Container, wobei letztere EJBs nur bis zur Version 3.0 vollständig unterstützt. Allerdings stehen den Vorteilen auch entsprechende Nachteile gegenüber. Aktuell unterstützten nicht alle Applikationsserver die Embedded Container. Einer der ersten Server mit einer umfangreichen Unterstützung ist Glassfish (vgl. [10]). Ein großer Nachteil der Embedded Container Lösung ist der begrenze Funktionsumfang. Die Spezifikation des Embedded Containers schreibt mindestens eine Implementierung des eingeschränkten EJB-Profils "EJB Lite" vor, wodurch der bereitgestellte Funktionsumfang des Embedded Containers je nach Anbieter variieren kann. Das "EJB Lite" Profil unterstützt beispielsweise keine Message Driven Beans, Remote Interfaces, Timer Services sowie EJB in der Version 2.0. JNDI Lookups sind aufgrund der fehlenden remote Interfaces deshalb nur auf lokale Interfaces beschränkt. Nützlich sind Tests zum einen wenn POJT nicht mehr ausreichen. Zu berücksichtigen ist allerdings, dass Tests innerhalb eines Embedded Container nur Aussagekräftig sind, wenn die Annahme gilt, dass das Verhalten des Embedded Containers mit dem des produktiv verwendeten Applikationsserver übereinstimmt.

Testen der installierten Applikation im Applikationsserver

Ein Testen der Applikation auf dem produktiv eingesetzten Applikationsserver sollte unabhängig vom Erfolg der Testdurchläufe mittels POJT oder Embedded Container immer durchgeführt werden. Einige Testszenarien wie Failover-, Integrations- oder Last- sowie Performanz-Tests können nur auf den Applikationsserver durchgeführt werden. Sind die Möglichkeiten des Testens für Embedded Container ausgeschöpft, verbleibt nur ein Testen auf dem "echten" Applikationsserver. Dieses Testverfahren ist im Bezug auf die bereits vorgestellten Verfahren wesentlich langsamer, da immer ein Deployment und ein Undeployment durchgeführt werden müssen. Um die Zeitdauer der Tests so gering wie möglich zu halten, bietet sich das sogenannte Micro-Deployment an. Bei diesem Verfahren werden nur die zu testenden Teile einer Anwendung auf dem Applikationsserver deployed. Mittels des Projekts Arquillian kann ein solches Micro-Deployment durchgeführt werden (vgl. [11]). Eine Übersicht des Projekts mit einem einführenden Beispiel kann unter [12] eingesehen werden.

Referenzen

[01] H.Rupp: EJB3 für Umsteiger - Neuerungen und Änderungen gegenüber dem EJB-2.X-Standard, dpunkt.verlag, Heidelberg, 2007
[02] W. Everling, J. Leßner: Enterprise JavaBeans 3.1: Das EjB3-Praxisbuch für Ein- und Umsteiger, 2. Auflage, Carl Hanser Verlag, München, 2011
[03] O. Ihns, S. Heldt, et. al: EJB 3.1 professionell - Grundlagen und Expertenwissen zu Enterprise JavaBeans 3.1 - inkl. JPA 2.0, 2., aktualisierte und erweiterte Auflage, dpunkt.verlag, Heidelberg, 2011
[04] JUnit: http://www.junit.org/, abgerufen am 10.11.2012
[05] TestNG: http://testng.org/doc/index.html, abgerufen am 10.11.2012
[06] mockito: http://code.google.com/p/mockito/, abgerufen am 10.11.2012
[07] EasyMock: http://www.easymock.org/, abgerufen am 10.11.2012
[08] OpenEJB: http://openejb.apache.org/downloads.html, abgerufen am 17.11.2012
[09] Cuba: Component Unification Base: http://cuba.sourceforge.net, abgerufen am 17.11.2012
[10] GlassFish - Open Source Application Server: http://glassfish.java.net, abgerufen am 17.11.2012
[11] Arquillian - Write Real Tests: http://arquillian.org/, abgerufen am 17.11.2012
[12] Integrationstests mit JBoss; Arquillian 1.0: www.heise.de/developer/artikel/Integrationstests-mit-JBoss-Arquillian-1-0-1519915.html, abgerufen am 17.11.2012

Zurück zu den Werkzeugen für JEE-Applikationen
Zurück zu den Werkzeugen