Wir bieten nun einen Gruppenrabatt an! Buche 2 Teilnehmer:innen und der/die Dritte ist kostenfrei.

Maven-Setup zum Testen von Java-Anwendungen

von Björn Wilmsmann

Dieser Artikel ist gesponsort von Philip (rieckpil) und aus dem Englischen übersetzt von workshops.de - Philip bietet einen umfassenden Online-Kurs zum Thema Testen von Spring Boot Anwendungen (englischsprachig) an.

- Deutsche Übersetzung von Justus Wildhagen -

Der Einstieg in eine neue Programmiersprache ist immer spannend. Es kann jedoch auch überwältigend sein, da wir uns mit der Sprache, den Werkzeugen, Konventionen und dem allgemeinen Entwicklungsablauf vertraut machen müssen. Dies gilt sowohl für die Entwicklung als auch für das Testen unserer Anwendungen. Beim Testen von Java-Anwendungen mit Maven gibt es mehrere Konzepte und Konventionen zu verstehen: Maven-Lifecycles, Build-Phasen, Plugins, etc. In diesem Blogbeitrag werden wir die grundlegenden Konzepte behandeln, um zu verstehen, wie das Testen von Java-Anwendungen mit Maven funktioniert.

Wofür brauchen wir Maven?

Wenn wir Anwendungen mit Java schreiben, können wir unsere .java-Dateien nicht einfach an die JVM (Java Virtual Machine) übergeben, um unser Programm auszuführen. Zuerst müssen wir unseren Java-Quellcode mit dem Java-Compiler (javac) in Bytecode (.class-Dateien) kompilieren. Anschließend übergeben wir diesen Bytecode an die JVM (java Binary auf unseren Rechnern), die dann unser Programm interpretiert und/oder Teile davon noch weiter in nativen Maschinencode kompiliert.

Angesichts dieses zweistufigen Prozesses muss jemand unsere Java-Klassen kompilieren und unsere Anwendung entsprechend verpacken. Der manuelle Aufruf von javac und die Übergabe des korrekten Classpaths ist eine mühsame Aufgabe. Ein Build-Tool automatisiert diesen Prozess. Als Developer müssen wir dann nur noch einen Befehl ausführen, und alles wird automatisch erstellt.

Die beiden am häufigsten verwendeten Build-Tools für das Java-Ökosystem sind Maven und Gradle. Ältere Entwickler:innen bevorzugen vielleicht immer noch Ant, während Entwickler:innen auf dem neuesten Stand sich für Bazel als Build-Tool für ihre Java-Anwendungen entscheiden könnten.

Wir fokussieren uns in diesem Artikel auf Maven.

Um unsere Java-Anwendungen zu erstellen und zu testen, benötigen wir ein JDK (Java Development Kit) auf unserem Rechner und Maven. Wir können entweder Maven als Kommandozeilen-Tool installieren (d.h. die Maven-Binärdatei in den PATH unseres Systems einfügen) oder den portablen Maven Wrapper verwenden.

Der Maven Wrapper ist ein bequemer Weg, um mit Maven zu arbeiten, ohne es lokal installieren zu müssen. Er ermöglicht es uns, Java-Projekte mit Maven zu erstellen, ohne Maven als CLI-Tool auf unserem Rechner installieren und konfigurieren zu müssen.

Wenn du beispielsweise ein neues Spring Boot-Projekt erstellen, hast du dich vielleicht schon gefragt, wofür die Dateien mvnw und mvnw.cmd im Root-Verzeichnis des Projekts verwendet werden. Das ist der Maven Wrapper (die Idee ist von Gradle ausgeliehen).

Erstellen eines neuen Maven-Projekts

Es gibt mehrere Möglichkeiten, ein neues Maven-Projekt zu bootstrappen. Die meisten der populären Java-Anwendungs-Frameworks bieten eine fast schon assistentenähnliche Schnittstelle für das Bootstrapping eines Projekts. Gute Beispiele sind der Spring Initializr für neue Spring Boot-Anwendungen, Quarkus, und MicroProfile.

Wenn wir ein neues Maven-Projekt ohne jeglichen Framework-Support erstellen wollen, können wir einen Maven Archetype verwenden. Diese Archetypen sind ein Projekt-Templating-Toolkit, um ein neues Maven-Projekt ganz bequem zu generieren.

Maven bietet eine Reihe von Standard Archetyp Artefakten für verschiedene Zwecke wie eine neue Web-App, ein neues Maven-Plugin-Projekt oder ein einfaches Quickstart-Projekt.

Wir bootstrappen ein neues Java-Projekt von einem dieser Archetypen, indem wir das mvn-Kommandozeilen-Tool benutzen:

mvn archetype:generate \
    -DarchetypeGroupId=org.apache.maven.archetypes  \
    -DarchetypeArtifactId=maven-archetype-quickstart \
    -DarchetypeVersion=1.4 \
    -DgroupId=com.mycompany \
    -DartifactId=order-service

Die Skeleton-Projekte, die wir mit den offiziellen Maven Archetypen erstellen, sind ein guter Ausgangspunkt.

Einige dieser Archetypen erzeugen jedoch Projekte mit veralteten Abhängigkeitsversionen wie JUnit 4.11. Es ist zwar kein großer Aufwand, die Abhängigkeitsversion nach der Projektinitialisierung manuell zu ändern, aber ein aktueller Maven Archetype von Anfang an ist auf jeden Fall besser.

Minimales Maven-Projekt zum Testen von Java-Anwendungen

Als Teil meines Custom Maven Archetype Open-Source-Projekts auf GitHub habe ich eine Sammlung von nützlichen Maven Archetypen veröffentlicht. Einer von ihnen ist das java-testing-toolkit, um ein Java-Maven-Projekt mit grundlegenden Testmöglichkeiten zu erstellen. Die Erstellung eines eigenen Maven Archetyps ist so gut wie überhaupt kein Aufwand.

Mit dem folgenden Maven-Befehl (für Linux & Mac) können wir ein neues Playground-Projekt erstellen, das diesen benutzerdefinierten Maven-Archetyp verwendet:

mvn archetype:generate \
    -DarchetypeGroupId=de.rieckpil.archetypes  \
    -DarchetypeArtifactId=java-testing-toolkit \
    -DarchetypeVersion=1.0.0 \
    -DgroupId=com.mycompany \
    -DartifactId=order-service

Für Windows (PowerShell & CMD) können wir den folgenden Befehl verwenden, um ein neues Projekt aus dieser Vorlage zu bootstrappen:

mvn archetype:generate "-DarchetypeGroupId=de.rieckpil.archetypes" "-DarchetypeArtifactId=testing-toolkit" "-DarchetypeVersion=1.0.0" "-DgroupId=com.mycompany" "-DartifactId=order-service" "-DinteractiveMode=false"

Wir können sowohl -DgroupId als auch -DartifactId an die Präferenzen unseres Projekts oder Unternehmens anpassen.

Das generierte Projekt enthält einen Basissatz der zentralsten Java-Testing-Bibliotheken. Wir können es als Blaupause für unser nächstes Projekt verwenden oder das Testen von Java-Anwendungen mit diesem Playground erkunden.

Insgesamt sind die folgenden Standardkonfigurationen und Bibliotheken Teil dieser Project-Shell:

  • Java 11
  • JUnit Jupiter, Mockito und Testcontainers-Abhängigkeiten
  • Basic Unit Test
  • Maven Surefire und Failsafe-Plugin-Konfiguration
  • Basic .gitignore
  • Maven Wrapper

Als nächstes müssen wir sicherstellen, dass ein JDK 11 (oder höher) in unserem Pfad (PATH) ist und dass JAVA_HOME auf den Installationsordner zeigt:

$ java -version
openjdk version "11.0.10" 2021-01-19
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.10+9)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.10+9, mixed mode)
 
# Windows
$ echo %JAVA_HOME%
C:\Program Files\AdoptOpenJDK\jdk-11.0.10.9-hotspot
 
# Mac and Linux
$ echo $JAVA_HOME
/usr/lib/jvm/adoptopenjdk-11.0.10.9-hotspot

Als finalen Schritt zur Verifizierung können wir nun dieses Projekt mit Maven erstellen und testen:

$ mvn archetype:generate ... // generate the project
$ cd order-service // navigate into the folder
$ ./mvnw package // mvnw.cmd package for Windows
 
....
 
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.326 s
[INFO] Finished at: 2021-06-03T08:31:11+02:00
[INFO] ------------------------------------------------------------------------

Wir können das Projekt jetzt öffnen und es in unseren Editor oder IDE (IntelliJ IDEA, Eclipse, NetBeans, Visual Studio Code, etc.) importieren, um das generierte Projekt genauer zu untersuchen.

Wichtige Testordner und Dateien

Werfen wir zunächst einen Blick auf die Ordner und Dateien, die für das Testen von Java-Anwendungen mit Maven relevant sind:

  • src/test/java

Dieser Ordner ist der wichtigste Ort, um unsere Java-Testklassen (.java-Dateien) hinzuzufügen. Als allgemeine Empfehlung sollten wir versuchen, die Paketstruktur unseres Produktionscodes (src/main/java) zu spiegeln. Vor allem, wenn es eine direkte Beziehung zwischen dem Test- und einer Quellcodeklasse gibt.

Der entsprechende CustomerServiceTest für eine CustomerService Klasse im Paket com.company.customer sollte im gleichen Paket innerhalb von src/test/java abgelegt werden. Dies erhöht die Wahrscheinlichkeit, dass unsere Kollegen (und wir natürlich auch) den entsprechenden Test für eine bestimmte Java-Klasse ohne allzu viel Ärger wiederfinden.

Die meisten IDEs und Editoren bieten weitere Unterstützung, um zu einer Testklasse zu springen. IntelliJ IDEA bietet beispielsweise eine Tastenkombination (Strg+Umschalt+T), um von einer Quelldatei zu ihren Testklassen zu navigieren und umgekehrt.

  • src/test/resources

In diesem Ordner speichern wir statische Dateien, die nur für unseren Test relevant sind. Dies kann eine CSV-Datei zum Importieren von Testkunden für einen Integrationstest, eine Dummy-JSON-Antwort zum Testen unserer HTTP-Clients oder eine Konfigurationsdatei sein.

  • target/test-classes

An diesem Ort platziert Maven unsere kompilierten Testklassen (.class Dateien) und Testressourcen, wann immer der Maven Compiler unsere Testquellen kompiliert. Wir können dies explizit mit mvn test-compile auslösen und ein clean hinzufügen, wenn wir zuerst den bestehenden Inhalt des gesamten target-Ordners entfernen wollen.

Normalerweise müssen in diesem Ordner keine manuellen Eingriffe vorgenommen werden, da er Build-Artefakte enthält. Nichtsdestotrotz ist es hilfreich, den Inhalt dieses Ordners zu untersuchen, wenn wir mit Testfehlern konfrontiert werden, zum Beispiel, weil wir eine Datei aus dem Classpath nicht lesen können. Ein Blick in diesen Ordner (nachdem der Maven-Compiler seine Arbeit getan hat), kann helfen zu verstehen, wo eine Ressourcendatei im Classpath gelandet ist.

  • pom.xml

Dies ist das Herzstück unseres Maven-Projekts. Die Abkürzung steht für Project Object Model. In dieser Datei definieren wir Metadaten über unser Projekt (z.B. Beschreibung, artifactId, Developers, etc.), die Konfiguration unserer Plugins und welche Abhängigkeiten wir benötigen.

Maven und Java-Test-Namenskonventionen

Werfen wir nun einen Blick auf die Namenskonventionen für unsere Testklassen. Wir können unsere Tests in zwei (oder sogar mehr) grundlegende Kategorien einteilen: Unit- und Integrationstests. Um die Tests für diese beiden Kategorien zu unterscheiden, verwenden wir in Maven unterschiedliche Namenskonventionen.

Das Maven Surefire Plugin, mehr dazu später, wurde entwickelt, um unsere Unit Tests auszuführen. Die folgenden Muster sind die Standardeinstellungen, damit das Plugin eine Klasse als einen Test erkennt.

  • **/Test*.java
  • **/*Test.java
  • **/*Tests.java
  • **/*TestCase.java

Aber was ist eigentlich ein Unit Test?

Mehrere kluge Köpfe haben eine Definition für diesen Begriff ausgearbeitet. Einer dieser klugen Leute ist Michael Feathers. Er dreht die Definition um und definiert, was ein Unit Test nicht ist:

Ein Test ist kein Unit Test, wenn er:

  • mit der Datenbank kommuniziert
  • über das Netzwerk kommuniziert
  • das Dateisystem berührt
  • nicht gleichzeitig mit anderen Unit-Tests ausgeführt werden kann
  • oder wenn du spezielle Dinge in deiner Umgebung vornehmen musst (z. B. Bearbeiten von Konfigurationsdateien), um ihn auszuführen.

Kevlin Henney ist ebenfalls eine gute Inspirationsquelle, wenn es um eine Definition der Begriffs Unit Test geht.

Unsere eigene Definition oder die Definition unserer Kollegen kann jedoch völlig anders sein. Letztendlich ist die tatsächliche Definition zweitrangig, solange wir innerhalb unseres Teams dieselbe Definition teilen und über dieselbe Sache sprechen, wenn wir uns auf den Begriff Unit Test beziehen.

Das Maven Failsafe Plugin, das für die Ausführung unserer Integrationstests entwickelt wurde, erkennt unsere Integrationstests anhand der folgenden Standardmuster:

  • **/IT*.java
  • **/*IT.java
  • **/*ITCase.java

Wir können auch die Standardmuster für beide Plugins überschreiben und eine andere Namenskonvention einführen. Es wird jedoch empfohlen, die Standardeinstellungen beizubehalten.

Wann werden unsere Java-Tests ausgeführt?

Maven ist um das Konzept der Build-Lifecycles herum aufgebaut. Es gibt drei eingebaute Lifecycles:

  • default: Handling von Projektbau und -einsatz
  • clean: Aufräumen des Projekts
  • site: Erstellung der (Dokumentations-)Site unseres Projekts

Jeder der drei eingebauten Lifecycles hat eine Liste von Build-Phasen. Für unser Testbeispiel ist der Lifecycle default wichtig.

Der “Standard”-Lifecycle umfasst eine Reihe von Build-Phasen zum Erstellen, Testen und Bereitstellen unseres Java-Projekts. Jede Phase steht für eine Stufe im Build-Lifecycle mit einer zentralen Verantwortung:

img

Kurz gesagt, haben die einzelnen Phasen folgende Verantwortlichkeiten:

  • validate: Überprüfung, ob unser Projekt korrekt eingerichtet ist (z. B., dass wir die richtige Maven-Ordnerstruktur haben)
  • compile: Kompiliern unseres Quellcodes mit javac
  • test: Ausführung unserer Unit Tests
  • package: Erstellung unseres Projekts in einem Auslieferungsformat (z.B. JAR oder WAR)
  • verify: Ausführung unseres Integrationstests und weitere Checks (z.B., der OWASP Abhängigkeits-Check)
  • install: Installation des Auslieferungsformat in unser lokales Repository (Ordner ~/.m2)
  • deploy: Bereitstellung des Projekts in einem Remote Repository (z. B. Maven Central oder ein vom Unternehmen gehostetes Nexus Repository/Artifactory)

Diese Build-Phasen stellen die zentralen Phasen des default-Lifecycle dar. Tatsächlich gibt es mehr Phasen. Eine vollständige Liste findest du in der Lifecycle-Referenz der offiziellen Maven Dokumentation.

Wann immer wir eine Build-Phase ausführen, wird unser Projekt alle Build-Phasen durchlaufen und zwar der Reihe nach bis zu der von uns angegebenen Build-Phase. Anders ausgedrückt, wenn wir zum Beispiel mvn package ausführen, wird Maven die Standard-Lifecycle-Phasen bis zu package der Reihe nach ausführen:

validate -> compile -> test -> package

Wenn eine der Build-Phasen in der Kette fehlschlägt, wird der gesamte Build-Prozess abgebrochen. Stell dir vor, in unserem Java-Quellcode fehlt ein Semikolon. Die compile-Phase würde dies erkennen und den Prozess beenden. Wie bei einer beschädigten Quelldatei gibt es keine kompilierte .class-Datei zum Testen.

Wenn es um das Testen unseres Java-Projekts geht, sind sowohl die test- als auch die verify-Build-Phase von Bedeutung. Als Teil der test-Phase führen wir unsere Unit Tests mit dem Maven Surefire Plugin aus, und bei verify werden unsere Integrationstests durch das Maven Failsafe Plugin ausgeführt.

Lasst uns einen Blick auf diese zwei Plugins werfen.

Ausführen von Unit Tests mit dem Maven Surefire Plugin

Das Maven Surefire Plugin ist für die Ausführung unserer Unit Tests verantwortlich. Wir müssen entweder der Standard-Namenskonvention unserer Testklassen folgen, wie oben beschrieben, oder ein anderes Muster konfigurieren, das unserer eigenen Namenskonvention entspricht. In beiden Fällen müssen wir unsere Tests im Ordner src/test/java ablegen, damit das Plugin sie abrufen kann.

Für die folgenden Beispiele verwenden wir eine einfache format-Methode.

public class Main {
 
  public String format(String input) {
    return input.toUpperCase();
  }
}

… und den dazugehörigen Test als Unit-Test-Blaupause:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
 
import static org.junit.jupiter.api.Assertions.assertEquals;
 
class MainTest {
 
  private Main cut;
 
  @BeforeEach
  void setUp() {
    this.cut = new Main();
  }
 
  @Test
  void shouldReturnFormattedUppercase() {
    String input = "duke";
 
    String result = cut.format(input);
 
    assertEquals("DUKE", result);
  }
}

Abhängig von der Maven-Version und dem Distributionsformat unserer Anwendung (z.B. JAR oder WAR), definiert Maven Standardversionen für die Core Plugins. Neben dem Maven Compiler Plugin, dem Maven Resource Plugin und anderen Plugins, ist das Maven Surefire Plugin ein solches Core Plugin.

Wenn wir unsere Anwendung als JAR-Datei verpacken und zum Beispiel Maven 3.8.1 verwenden, wählt Maven standardmäßig das Maven Surefire Plugin in der Version 2.12.4 aus, es sei denn, wir überschreiben es. Da die Standardversionen manchmal ein wenig hinter den neuesten Plugin-Versionen hinterherhinken, lohnt es sich, die Plugin-Versionen zu aktualisieren und die Plugin-Version manuell in unserer pom.xml anzugeben:

<project>
  <!-- dependencies -->
 
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.0.0-M5</version>
      </plugin>
    </plugins>
  </build>
 </project>

Als Teil der test-Phase des Standard-Lifecycle werden wir nun sehen, wie das Maven Surefire Plugin unsere Tests ausführt:

$ mvn test

[INFO] --- maven-surefire-plugin:3.0.0-M5:test (default-test) @ testing-example ---
[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running de.rieckpil.blog.MainTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.04 s - in de.rieckpil.blog.MainTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------

Im obigen Beispiel führen wir einen Unit Test mit JUnit 5 (Testing Provider) aus. Es besteht keine Notwendigkeit, den Testing Provider irgendwo zu konfigurieren, da das Plugin bei neueren Surefire-Versionen den korrekten Testing Provider selbständig auswählt. Das Maven Surefire Plugin integriert sowohl JUnit als auch TestNG als Testing Provider und macht sie sofort einsatzbereit.

Wenn wir nicht alle Build-Phasen ausführen wollen, bevor wir unsere Tests starten, können wir auch explizit das test-Ziel des Surefire-Plugins ausführen:

mvn surefire:test

Denke aber daran, dass wir sicherstellen müssen, dass die Testklassen zuerst kompiliert wurden (z.B. durch einen früheren Build).

Wir können das Maven Surefire Plugin weiter optimieren und konfigurieren, um z.B. die Ausführung unserer Unit Tests zu parallelisieren. Dies ist nur für JUnit 4 relevant, da JUnit 5 (JUnit Jupiter, um genau zu sein) die Parallelisierung auf der Ebene des Test-Frameworks unterstützt.

Wann immer wir unsere Unit-Tests beim Erstellen unseres Projekts überspringen wollen, können wir einen zusätzlichen Parameter verwenden:

mvn package -DskipTests

Wir können auch explizit nur einen oder mehrere Tests durchführen:

mvn test -Dtest=MainTest
 
mvn test -Dtest=MainTest#testMethod
 
mvn surefire:test -Dtest=MainTest

Ausführen von Integrationstests mit dem Maven Failsafe Plugin

Im Gegensatz zum Maven Surefire Plugin ist das Maven Failsafe Plugin kein Core Plugin und wird daher nicht Teil unseres Projektes sein, es sei denn wir binden es manuell ein. Wie bereits beschrieben, wird das Maven Failsafe Plugin verwendet, um unseren Integrationstest auszuführen.

Im Unterschied zu unseren Unit Tests nehmen die Integrationstests in der Regel mehr Zeit in Anspruch, sind aufwändiger einzurichten (siehe z.B. diesen Artikel zum Starten von Docker Containern für externe Infrastruktur mit Testcontainers) und testen mehrere Komponenten unserer Anwendung gemeinsam.

Wir integrieren das Maven Failsafe Plugin, indem wir es zum build-Abschnitt unserer pom.xml hinzufügen:

<project>
  
  <!-- other dependencies -->
 
  <build>
    <!-- further plugins -->
    <plugin>
      <artifactId>maven-failsafe-plugin</artifactId>
      <version>3.0.0-M5</version>
      <executions>
        <execution>
          <goals>
            <goal>integration-test</goal>
            <goal>verify</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </build>
</project>

Als Teil der executions-Konfiguration spezifizieren wir die Ziele des Maven Failsafe Plugins, die wir als Teil unseres Build-Prozesses ausführen wollen. Ein häufiger Fallstrick ist es, nur das Ziel integration-test auszuführen. Ohne das verify-Ziel, wird das Plugin unsere Integrationstests zwar ausführen, aber den Build nicht fehlschlagen lassen, wenn es Testfehler gibt.

Das Maven Failsafe Plugin wird als Teil der verify-Build-Phase des Standard-Lifecycle aufgerufen. Das ist direkt nach der package Build Phase, in der wir unser auslieferbares Artefakt (z.B. JAR) bauen:

[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ testing-example ---
[INFO] Building jar: C:\Users\phili\Desktop\junk\testing-example\target\testing-example.jar
[INFO]
[INFO] --- maven-failsafe-plugin:3.0.0-M5:integration-test (default) @ testing-example ---
[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running de.rieckpil.blog.MainIT
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.039 s - in de.rieckpil.blog.MainIT
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- maven-failsafe-plugin:3.0.0-M5:verify (default) @ testing-example ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

Wenn wir unsere Integrationstests manuell ausführen wollen, können wir dies mit dem folgenden Befehl tun:

mvn failsafe:integration-test failsafe:verify

Für Szenarien, in denen wir unseren Integrationstest nicht ausführen wollen (aber unsere Unit Tests schon), können wir -DskipITs zu unserem Maven Aufruf hinzufügen:

mvn verify -DskipITs

Ähnlich wie beim Maven Surefire Plugin können wir auch eine Teilmenge unserer Integrationstests ausführen:

mvn -Dit.test=MainIT failsafe:integration-test failsafe:verify

mvn -Dit.test=MainIT#firstTest failsafe:integration-test failsafe:verify

Wenn du den obigen Befehl verwendest, vergewissere dich, dass die Testklassen zuvor kompiliert wurden, da sonst kein Test ausgeführt werden kann.

Es gibt auch einen Parameter, mit dem die Kompilierung von Testklassen komplett übersprungen werden kann und der das Ausführen jeglicher Tests beim Erstellen unseres Projekts verhindert (nicht empfohlen):

mvn verify -Dmaven.test.skip=true

Zusammenfassung des Testens von Java-Anwendungen mit Maven

Maven ist ein leistungsfähiges, ausgereiftes und gut angenommenes Build-Tool für Java-Projekte. Als Neueinsteiger:in oder wenn du von einer anderen Programmiersprache kommst, ist es wichtig, zuerst die Grundlagen des Maven-Build-Lifecycle zu verstehen und wie und wann die verschiedenen Maven-Plugins interagieren.

Mithilfe von Maven Archetypen oder einem Framework-Initialisierer können wir neue Maven-Projekte einfach bootstrappen. Es besteht keine Notwendigkeit, Maven als CLI-Tool für unseren Rechner zu installieren, da wir stattdessen den portablen Maven Wrapper verwenden können.

Desweiteren solltest du dies im Hinterkopf behalten, wenn du deine Java-Anwendungen testest und Maven als Build-Tool verwendest:

  • Mit Maven können wir die Ausführung von Unit- und Integrationstests trennen
  • Das Maven Surefire Plugin führt unsere Unit Tests aus
  • Das Maven Failsafe Plugin führt unsere Integrationstests aus
  • Indem wir die Standard-Namenskonventionen für beide Plugins befolgen, können wir unsere Tests einfach trennen
  • Der Standard-Lifecycle von Maven besteht aus mehreren Build-Phasen, die nacheinander und in der richtigen Reihenfolge ausgeführt werden
  • Verwende den Java Testing Toolkit Maven Archetype für dein nächstes Testabenteuer

Wenn du weitere praktische Ratschläge zum Testen von Java benötigst, solltest du dich für den kostenlosen 14-tägigen E-Mail-Kurs zum Testen anmelden, der dir eine Einführung in das Java-Testing-Ökosystem mit Tipps und Tricks für Unit-, Integrations- und End-to-End-Tests gibt.

Der Quellcode für diesen Artikel über das Testen von Java-Anwendungen mit Maven ist auf GitHub verfügbar.

Frohes Testen!

Dieser Artikel ist gesponsort von Philip (rieckpil) und aus dem Englischen übersetzt von workshops.de - Philip bietet einen umfassenden Online-Kurs zum Thema Testen von Spring Boot Anwendungen (englischsprachig) an.

Geschrieben von

Mein Name ist Björn. Ich bin freiberuflicher IT Berater, Trainer und Autor. Ich beschäftige mich mit Enterprise Anwendungen und Web Apps. Mein technologischer ...