Probleme mit der Testing-Struktur

DaBe1812

Mitglied
Hallo zusammen,

ich habe jetzt endlich in der Projektleitung zumindest ein wenig Zeit bekommen, um mehr JUNIT-Tests zu schreiben. Deswegen hatte ich jetzt zum neuen Release mehr davon geschrieben, allerdings habe ich scheinbar einen Denkfehler.

In unserer Anwendung rufen wir viele andere Anwendungen per Rest-Call an, um dort hauptsächlich Daten abzufragen. Deswegen habe ich eine Integration des Http-Client gebaut und an dieser hängen dann mehrere Integrationen der anderen Anwendungen, in denen ich dann den Allgemeinen kram regele, wie z.B. ein Login aufgebaut wird, oder wie muss die URL gebaut werden, um auf einen bestimmten Funktionsbaustein zu kommen.

Diese Klassen wollte ich testen, weil ein Fehler in den Methoden durch winzige Änderungen eben riesige Auswirkungen haben kann. Ist ja quasi der Standard für JUnit.

Die Testfälle laufen aber direkt gegen die anderen Systeme. Soweit eigentlich für mich erstmal kein Problem. Aber, jetzt hatten wir letzte Woche den Fall, dass wir einen Fehler fixen wollten und zum abschließenden Test sollte die Anwendung auf den Entwicklungsserver und der Build lief nicht durch, weil eine komplette Testklasse auf Fehler lief, weil das Gegensystem gerade ein Update bekommen hat und deswegen nicht zur Verfügung stand.

Ich weiß, für solche Fälle soll man das Ganze eben mocken, dann ist man auf das externe System nicht angewiesen, aber hier verstehe ich die Sache nicht 100%tig:
Ich gehe also hin, rufe meine Funktion auf und mocke eben die Antwort, die ich erwarte, dass sie bei diesem Aufruf vom Server kommt. Soweit so gut. Aber wir hatten schon den Fall, dass meine Klassen nicht mehr funktioniert haben, weil die andere Anwendung ein Major-Update bekommen hat und deswegen ein paar Funktionsbausteine verschoben worden sind. Jetzt würde mein Test durchlaufen, aber im Real-Fall geht er auf die Bretter, weil die erwartete Antwort nicht mehr die echte Antwort ist.

Für einen Fall, wie letzte Woche würde mir reichen, wenn gemockte Tests durchlaufen, aber sollten wir gesagt bekommen, dass eine andere Anwendung ein Update bekommen hat, dann hätte ich gerne die Möglichkeit automatisiert zu prüfen, ob alle meine Klassen dazu noch funktionieren, oder irgendwo anpassungsbedarf ist.

Wie mache ich das in der Praxis?
 

KonradN

Super-Moderator
Mitarbeiter
Du hast zwei unterschiedliche Tests:
  • Unit Tests - diese testen Units, also ausschließlich Deine Klassen / Methoden. Daher Mockst du andere Komponenten, denn Fehler in diesen Komponenten sollen eben nicht dazu führen, dass Deine Tests fehlschlagen.
  • Integrations Tests - in diesen Tests wird getestet, ob die Integration in den Zielbereich funktioniert. Da wäre also dann der Test, ob das Ansprechen der jeweiligen Schnittstellen wirklich funktioniert.

Wenn ihr mehrere Systeme habt mit REST Schnittstellen, auf die zugegriffen wird: Hier ist unser Vorgehen, dass wir diese APIs immer sauber dokumentieren (OpenAPI/Swagger) und die Clients generieren sich daraus dann alles für die Schnittstelle. Änderungen an der API führen dann zu Fehlern beim Build, weil die generierten Klassen halt nicht mehr zum Code passen.

(Wobei ich mich ein wenig wundere - das sind dann alles APIs, die zusammen gehören, d.h. es ist ein Team, das da an allem arbeitet? Denn dann wäre meine Erwartung etwas, dass es auch alles zusammen hängt (so haben wir es zumindest bei uns). Wenn dann so breaking Changes kommen, dann haben wir halt auch direkt die Anpassung, dass wieder alles funktioniert da in einem großen Maven Projekt zusammen,
Wenn es über mehrere Teams geht / unterschiedliche Produkte sind, dann wäre meine Erwartung, dass es da eine deutlich bessere Organisation von API Changes gibt. Bei Breaking Changes wäre dann sogar die Frage, in wie weit es sogar Sinn machen kann, da eine neue Version zu bauen. Aber zumindest wäre da halt eine saubere Kommunikation wichtig, bei der die API zuerst dokumentiert wird um dann zu sagen: Mit der Version xyz wird ab xx.yy.zzzz dann diese neue API gelten.
==> Du kannst da vorab auch Deinen Code anpassen und dann wirst Du auch keine Probleme mit den API Aufrufen bei den Integrationstests haben. Das muss dann auch sauber dokumentiert sein. Unsere Version 1.1.0 braucht API 2.7.3 und nicht mehr API 2.7.2. Und die Version 1.0.9 brauchte halt API 2.7.2 und dann wird immer klar gewesen sein: Mit API 2.7.3 kann es Probleme geben. Und wenn man Probleme hat, dann schaut man in die Release Notes und da sollte bei der API 2.7.3 auch ganz klar der Breaking Change enthalten sein.

Das einfach einmal als kleine Übersicht, wie wir arbeiten und vorgehen.
 

DaBe1812

Mitglied
Alles klar. Das verstehe ich.
Also es ist Fremdsoftware, gegen die ich entwickle und Kommunikation wir hier relativ klein geschrieben. Manche Abteilungen haben noch einen Überblick, über die Nutzer ihrer Schnittstellen und schicken zumindest einen freundlichen Reminder, dass an einem bestimmten Wochenende ein Update stattfindet. Machmal sogar erst im Test, dann kann man gegen Test entwickeln und plant sein Release eben zu deren Produktivsetzung.
Andere Abteilungen schicken sogar Release-Notes mit rum, da erwarte ich dann auch zu sehen, dass sich etwas an der REST-API geändert hat. Und dann gibt es die "wichtigen" Projekte, die interessieren sich nicht dafür, wer sie nutzt und wer nicht, da kommen dann zu den Releases noch 3 Fixe und Montags stellet man dann fest, dass seit Samstag nix mehr funktioniert.

Aber das soll hier nicht Thema sein.
Du hast jetzt sogar zwei Sachen bei mir aufgeworfen:
1. Strukturierung
Sollte ich mein Projekt jetzt anders strukturieren. Also sollte es unter src jetzt drei Ordner geben, main, test und integration? Und wie triggere ich das in Maven, dass zum Build nur test getestet wird und wie kann ich integration gezielt triggern?

2. Eigene Rest-Schnittstelle
Dieses Jahr wollen wir eine eigene Rest-Schnittstelle etablieren. Die hätte ich auch gerene als eigenes Modul, mit eigenem RootContext im IntelliJ-Projekt. Aktuell gibt es für das Projekt nur eine Versions-Nummer in der Root-Pom. Sollte ich dann evtl. der Rest-Api eine eigene Versionsnummer geben?
Also jetzt mit der nächsten Version vielleicht eine 0.x um zu sehen, ob die API auch produktiv funktioniert und danach eine 1.0 und dann halt nur, wenn sich in der aktuellen Version etwas ändert?
 

mihe7

Top Contributor
Also sollte es unter src jetzt drei Ordner geben, main, test und integration?
Nope (edit: wobei Du das natürlich machen könntest). Du verwendest das failsafe-Plugin und benennst Deine Integrations-Textklassen mit "IT" am Ende (oder am Anfang), also z. B. MeinServiceTestIT.

Und wie triggere ich das in Maven, dass zum Build nur test getestet wird und wie kann ich integration gezielt triggern?
Mit Profilen.

Siehe zum Beispiel https://www.baeldung.com/maven-integration-test
 

DaBe1812

Mitglied
Okay, der Baeldung-Artikel ist ja äußerst umfangreich. Jetzt muss ich bei MAven nachfragen, was mehr Sinn macht bei einem Projekt mit mehreren Modulen:
Das Plugin in jedem Modul bei Build mit einbinden, oder das Plugin in der Main-Pom einbinden und dann macht er schon in den Poms darunter, was er soll?
Da sind ja auch Poms dabei, komplett ohne Tests, die z.B. nur das EAR-File erstellen, oder bestimmte Dateien für das Deployment packen.

Das Beispiel mit dem Jetty-Server würde ja dann in Zukunft interessant werden, wenn wir eine eigene Rest-Schnittstelle anbieten. Aber eben nur für das Rest Modul und nicht für alle anderen.
 

mihe7

Top Contributor
Wir konfigurieren im POM-Projekt (dem Wurzel-Projekt) per <dependencyManagement> bzw. <pluginManagement> die Abhängigkeiten bzw. Plugins und in den Modulen wird dann die betreffende Dependency/das Plugin (ohne Versionsangabe) hinzugefügt.

Nachtrag:
Beispielsweise im Parent
XML:
<pluginManagement>
  <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>3.5.3</version>
        <executions>
          <execution>
            <goals>
              <goal>integration-test</goal>
              <goal>verify</goal>
            </goals>
          </execution>
        </executions>
      </plugin>    
  </plugins>
</pluginManagement>

und im Modul, in dem der Spaß tatsächlich verwendet werden soll, wird dann nur noch referenziert:
XML:
<build>
  <plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
    </plugin>
  </plugins>
</build>
 
Zuletzt bearbeitet:

DaBe1812

Mitglied
Ja, eigentlich habe ich das komplette DependencyManagement in die Root-POM gelegt, aber gestern hatten wir einen ganz seltsamen Fehler beim Import von Excel-Dokumenten und es stellte sich heraus, dass jemand ein zweites Apache POI mit einer anderen Version in ein Modul direkt importiert hat. Da gab es erstmal eine Ansprache.
Die Plugins werde ich dann wohl auch mal ins Management in die Root verschieben, allein schon wegen der Versionsverwaltung. Da war ich mir allerdings immer nicht sicher, ob das so richtig ist.
Dein Beispiel macht mir einiges klarer, weil ich mir mit der Konfiguration unsicher war, also ob z.B. <executions> mit in das Management gehört, oder nicht. Nicht, dass wir da etwas hätten, aber in der POM, in der dann so ein gemanagtes Plugin verwendet wird, da könnte ich z.B. <executions> nochmal überschreiben? Wenn ich z.B. ein Plugin in mehreren Modulen verwende, aber immer mit einer leicht anderen Konfiguration, wie z.B. Pfaden?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Dimax JSP Probleme mit Java in JSP Allgemeines EE 21
OnDemand Performance Probleme wegen vieler Objekte Allgemeines EE 3
B @Startup - FileWatcher - Probleme beim Hochfahren des Servers Allgemeines EE 4
Psypsy Spring Probleme mit Datenzugriff Allgemeines EE 5
D Apache POI Probleme mit Daten(Datum) die aus Formeln entstehen Allgemeines EE 3
T Probleme mit File renameTo bzw. File delete @@ Allgemeines EE 3
F Probleme mit JSF und ManagedBean Allgemeines EE 3
B Probleme mit Templates in einem Webprojekt Allgemeines EE 6
Fu3L Probleme beim Einrichten Allgemeines EE 3
A Probleme bei der Einbindung eines Liferay Portalserver (Glassfish) Allgemeines EE 7
S Datenbankzugriff (Probleme mit Cache?!) Allgemeines EE 8
K Probleme mit Apache MyFaces 2 und ICEFaces Facelets Allgemeines EE 1
K Probleme mit Enterprise Anwendung Allgemeines EE 5
D Probleme mit Cactus Allgemeines EE 9
F <security-constraint> Probleme Allgemeines EE 2
G Probleme im Tomcat - loading WebappClassLoader Allgemeines EE 3
T Probleme mit ApplikationClient mit Sicherheitsanmeldung! Allgemeines EE 2
G Probleme mit dem Klassenpfad nach dem deployment Allgemeines EE 2
Q Probleme bei einbinden von RichFaces. Allgemeines EE 10
T Probleme mit Facelets und if foreach und when Allgemeines EE 3
V Bildupload probleme Allgemeines EE 2
T Probleme mit Komplexerer ejb-ql Abfrage! Allgemeines EE 2
R EJB Client: Probleme mit der Client.jar Allgemeines EE 2
M Probleme mit Leerzeichen bei HtmlOutputLink Allgemeines EE 5
K probleme mit <h:dataTable> Allgemeines EE 2
M probleme mit client server kommunikation Allgemeines EE 3
S Probleme mit struts - ActionServlet Allgemeines EE 6
E BackingBean Probleme Allgemeines EE 2
K JBoss AS & IDE Probleme Allgemeines EE 2
T Probleme beim Einsatz von J2EE / JBoss Allgemeines EE 4
Ö Spring, Probleme mit FlowScope und HttpServletRequest Allgemeines EE 2
J Probleme mit Struts Allgemeines EE 3
DaRolla Probleme mit Verzeichnissen (Servlet, JSP, Tomcat) Allgemeines EE 8
G Probleme mit ResultSet Allgemeines EE 9
L Probleme mit Kompilierung von JNDI Allgemeines EE 2
K Internet Explorer MIME Type Probleme Allgemeines EE 2
M Probleme beim Performancetuning des Servlets Allgemeines EE 2
G Probleme mit Validierung (Struts, validation.xml) Allgemeines EE 4
G Mehrere Probleme mit Servlets/Java Allgemeines EE 15
W Tomcat Probleme Allgemeines EE 7
FsMarine Probleme beim ausführen von JSP dateien unter Tomcat Allgemeines EE 4
E JBoss 4.0.2 - Probleme mit der Spezifikation Allgemeines EE 3
R Probleme mit Tutorial Allgemeines EE 4
M Probleme bei Aufruf von JSPs in Unterverzeichnissen Allgemeines EE 2
M Probleme beim Webservice Deployment(Sun ApplicationServer) Allgemeines EE 2
H JONAS 4.1.4 Start Probleme Allgemeines EE 2
O Probleme mit Aktualität bei JBOSS Allgemeines EE 4
A Probleme mit J2EE und Tomcat Allgemeines EE 7
R Inputstream Probleme Allgemeines EE 11
P Probleme mit File renameTo bzw. File delete Allgemeines EE 3
F Probleme mit Eclipse/JBoss Allgemeines EE 6
G JSF, Hibernate, Spring --> Struktur Allgemeines EE 2
U File upload, File download und verzeichnis Struktur Allgemeines EE 2

Ähnliche Java Themen

Neue Themen


Oben