Wer Arquillian in einem Maven Multi-Modul-Projekt einsetzen wollte, stand sicherlich ebenfalls vor der Frage, wann und wie das Test EAR Archive erstellt werden soll. Dies ist bis zu dem Zeitpunkt dieses Beitrags ein fehlendes Feature des ShrinkWrap Resolver (https://issues.jboss.org/browse/SHRINKRES-98)
Betrachten wir die folgende Projektstruktur:
Parent ----- common src/test/java/CommonArquillianTest.java ----- persistence src/test/java/PersistenceArquillianTest.java ----- services src/test/java/ServicesArquillianTest.java ----- presentation src/test/java/PresentationArquillianTest.java ----- ear
Wenn Maven das Projekt in dieser Reihenfolge baut, ist zum Zeitpunkt der Ausführung vom CommonArquillianTest das Zusammenstellen von einem EAR Archive noch nicht möglich, weil die anderen Module noch nicht gebaut und verfügbar sind. Dies ist der Fall, weil Maven die einzelnen Module mit dem gesamten Build Lifecycle compile, test, package etc. nacheinander baut.
Um dieses Problem zu umgehen bestehen zwei Möglichkeiten:
- Teilmodule mit dem ShrinkWrap Resolver MavenImporter bauen und in einem fake Web Archive packen.
- Ein Test-Modul hinzufügen in dem die Tests für das gesamte Projekt definiert werden. Das Test Modul soll im Build Prozess als letztes ausgeführt werden, somit wird sichergestellt, dass alle Projekt-Module schon gebaut und zum Erstellen eines Test EAR Archives verfügbar sind.
Der erste Lösungsansatz ist umständlicher bei der Umsetzung und schlechter, was die Wartbarkeit betrifft. Der zweite Ansatz ist einfacher und löst auch das Problem der gemeinsamen Nutzung von Test Ressourcen in einem Multi-Modul-Projekt (siehe http://stackoverflow.com/questions/14722873/sharing-src-test-classes-between-modules-in-a-multi-module-maven-project).
Bei verteilter Projektentwicklung, in der verschiedene Teams an den Projekt-Modulen arbeiten, ist das Hinzufügen eines gemeinsamen Test-Modules nicht immer möglich. Die Entscheidung, welcher Ansatz im eigenen Projekt einzusetzen ist, hängt von verschiedenen Faktoren ab. Dies wird im Rahmen dieses Beitrags nicht weiter diskutiert.
Im Folgenden wird die Arquillian Integration in einem Multi-Modul-Projekt anhand eines neuen Test-Moduls näher beschrieben.
Neue Projektstruktur.
Parent ----- common ----- persistence ----- services ----- presentation ----- ear ----- test src/test/java/common/CommonArquillianTest.java src/test/java/persistence/PersistenceArquillianTest.java src/test/java/services/ServicesArquillianTest.java src/test/java/presentation/PresentationArquillianTest.java
In der Beispielprojektstruktur wird das EAR Archive innerhalb des EAR Modules erzeugt. Das Test-Modul wird als letztes von Maven gebaut und die Arquillian Testklassen können das fertige EAR Archive mittels ShrinkWrap ZipImporter direkt benutzen.
EnterpriseArchive archive = ShrinkWrap.create(ZipImporter.class, TEST_EAR_NAME).importFrom(new File(PATH_TO_INTEGRATION_EAR)).as(EnterpriseArchive.class);
In der Regel werden testspezifische Konfigurationsdateien in das importierte Archiv eingefügt. Dies kann sowohl auf Archiv-Ebene als auch auf Modul-Ebene gemacht werden.
archive.addAsApplicationResource("config/test-application.xml", "application.xml"); archive.getAsType(JavaArchive.class, "lib/persistence.jar").addAsManifestResource("config/test-persistence.xml", "persistence.xml");
Außerdem stellt sich für den Build Prozess die Frage, wann welche Tests durchgeführt werden sollen. Dafür gibt es wiederum verschiedene Ansätze wobei meistens Junit und Integrationstest in verschiedenen Phasen durchgeführt werden und deshalb auch auf Testklassenebene unterschieden werden sollen. Dazu kann die Junit @Category Annotation mit Marker Interfaces benutzt werden.
@RunWith(Arquillian.class) @Category(IntegrationTest.class) public class AccountDaoIntegrationTest {
@Category(UnitTest.class) public class AccountDaoTest {
IntegrationTest.class und UnitTest.class sind zwei Marker Interfaces mit leerem Inhalt
public interface IntegrationTest {}
Soll für den Default Build Profile nur Unit Tests ausgeführt werden ist dies einfach über die groups property des maven-surfire-plugin konfigurierbar.