In unserer Testumgebung gibt es eine Vielzahl von Integrationstests, die auf Middleware basieren (CMS-Plattform, zugrunde liegende Datenbank, Elasticsearch-Index).
Sie sind automatisiert und wir verwalten unsere Middleware mit Docker, sodass wir keine Probleme mit unzuverlässigen Netzwerken haben. Allerdings stürzt unsere DB manchmal ab und unser Test schlägt fehl.
Das Problem besteht darin, dass die Erkennung dieses Fehlers durch eine Litanei von org.hibernate.exception.JDBCConnectionException
messages erfolgt. Diese entstehen durch eine Zeitüberschreitung. Wenn das passiert, enden Hunderte von Tests mit dieser Ausnahme, die jeweils einige Sekunden dauern. Daher dauert es ein Alter für unsere Tests abzuschließen. Tatsächlich töten wir diese Builds im Allgemeinen einfach manuell, wenn wir erkennen, dass sie fertig sind.
Meine Frage: Gibt es in einer Maven-gesteuerten Java-Testumgebung eine Möglichkeit, das Build-System anzuweisen, bestimmte Arten von Ausnahmen zu überwachen und den gesamten Prozess zu beenden, falls sie ankommen (oder eine Art Schwelle erreichen)?
Wir könnten unsere Container überwachen und den Build-Prozess auf diese Weise beenden, aber ich hoffe, dass es einen saubereren Weg gibt, es mit maven zu machen.
Wenn Sie TestNG anstelle von JUnit verwenden, gibt es andere Möglichkeiten, Tests als abhängig von anderen Tests zu definieren.
Wie oben erwähnt, können Sie beispielsweise eine Methode verwenden, um Ihre Datenbankverbindung zu überprüfen und alle anderen Tests als von dieser Methode abhängig zu erklären.
%Vor% Wenn der serverIsReachable
Test fehlschlägt, werden alle anderen Tests, die von diesem Test abhängen, übersprungen und nicht als fehlgeschlagen markiert . Übersprungene Methoden werden im endgültigen Bericht als solche gemeldet, was wichtig ist, da übersprungene Methoden nicht unbedingt Fehler sind. Aber Da der erste Test serverIsReachable
fehlgeschlagen ist, sollte der Build vollständig fehlschlagen.
Der positive Effekt ist, dass keine Ihrer anderen Tests ausgeführt werden, die sehr schnell ausfallen sollten .
Sie können diese Logik auch mit Gruppen erweitern. Angenommen, Ihre Datenbankabfragen werden anschließend von einigen Domänenlogiktests verwendet. Sie können jeden Datenbanktest mit einer Gruppe wie
deklarieren %Vor%und deklarieren Sie Domänenlogiktests als abhängig von diesen Tests mit
%Vor%TestNG garantiert daher die Reihenfolge der Ausführung für Ihre Tests.
Ich hoffe, dies hilft, Ihre Tests strukturierter zu gestalten. Weitere Informationen finden Sie in der Dokumentation zur TestNG-Abhängigkeit .
Ich weiß, dass dies nicht genau das ist, wonach Sie fragen, aber es könnte trotzdem helfen, den Build zu beschleunigen:
JUnit-Annahmen ermöglichen, dass ein Test bestanden wird, wenn eine Annahme fehlschlägt. Sie könnten eine Annahme wie assumeThat(db.isReachable())
haben, die diese Tests überspringt, wenn ein Timeout erreicht wird.
Um die Dinge tatsächlich zu beschleunigen und nicht immer wieder zu wiederholen, könntest du dies in @ClassRule
:
Eine fehlgeschlagene Annahme in einer @Before-Methode oder @BeforeClass-Methode hat den gleichen Effekt wie eine fehlgeschlagene Annahme in jeder @Test-Methode der Klasse.
Aus diesem Grund müssten Sie Ihren Build dann auf eine andere Weise als instabil markieren, aber das sollte leicht machbar sein.
Ich weiß nicht, ob Sie den Build selbst scheitern können - oder sogar wollen -, da die administrativen Aspekte des Builds möglicherweise nicht vollständig sind, aber Sie könnten dies tun:
Fügen Sie in all Ihren Testklassen, die von der Datenbank abhängen - oder von den übergeordneten Klassen, da etwas so vererbbar ist - Folgendes hinzu:
%Vor%Wenn die einfache JDBC-Abfrage nicht innerhalb von 100 ms zurückgegeben wird, wird die gesamte Testklasse nicht ausgeführt und wird als "fehlgeschlagen" für den Build angezeigt.
Machen Sie die Wartezeit so klein wie möglich und immer noch zuverlässig.
Eine Sache, die Sie tun könnten, ist, einen neuen Test-Runner zu schreiben, der stoppt, wenn solch ein Fehler auftritt. Hier ist ein Beispiel, wie das aussehen könnte:
%Vor% Dann kommentieren Sie Ihre Testklassen mit @RunWith(StopAfterSpecialExceptionRunner.class)
.
Im Grunde geht es darum, dass es nach einer bestimmten Exception sucht (hier ist es SpecialException
, eine Exception, die ich selbst geschrieben habe) und wenn das passiert, wird der Test fehlschlagen und alle folgenden Tests überspringen. Sie könnten das natürlich auf Tests beschränken, die mit einer bestimmten Anmerkung kommentiert werden, wenn Sie möchten.
Es ist auch möglich, dass ein ähnliches Verhalten mit Rule
erreicht werden kann, und wenn das so ist, kann es viel sauberer sein.
Tags und Links java maven integration-testing