Integrationstests – auf welcher Ebene testen Sie?

Hi,

Mein Name ist Michael. Ich bin ein Softwareentwickler aus Nottingham und arbeite derzeit bei Experian Consumer Services. In meiner täglichen Arbeit komme ich mit viel Code in Berührung, der von vielen verschiedenen Leuten geschrieben wurde. Diese Geschichte folgt einem meiner jüngsten Streifzüge in unsere Codebasis und enthüllt Ihnen, was ich herausgefunden habe, damit Sie diese Falle vermeiden können.

Der Titel dieses Beitrags sollte laut Edsger Dijkstras berühmtem Artikel „Go To Statement Considered Harmful“ eigentlich „E2E-Tests gelten als schädlich“ lauten. Sie denken vielleicht: „Ich führe die ganze Zeit E2E-Tests durch und sie finden viele Fehler!“ Ich argumentiere nicht für das Fehlen von E2E-Tests. Ich plädiere jedoch für weniger E2E-Tests zugunsten von mehr Tests auf Integrationsebene.

Kürzlich habe ich mir unsere Testsuite angesehen und mich gefragt, warum unsere Tests sporadisch fehlschlagen. Die Art und Weise, wie wir unsere automatisierten Testsuiten ausführen (ohne Komponententests, wohlgemerkt), besteht darin, einen Jenkins-Job von einem Travis-Build auszulösen, nachdem die Bereitstellung des neuesten Codes in unserer Entwicklungsumgebung abgeschlossen ist. Das bedeutet, dass der Pull-Request im GitHub-Jargon bereits mit Mainline zusammengeführt wurde.

Dabei kann man bereits ein Problem erkennen: Was ist, wenn die Integrationstests fehlschlagen? Am Ende müssen Sie nur noch verzweigen, festschreiben, genehmigen, zusammenführen – wieder. Für mich schien dies ein übermäßiger Overhead zu sein. Wir brauchten keinen Jenkins-Job für unsere Integrationstests, wir brauchen diese lange Feedback-Schleife nicht. Idealerweise würden wir unsere Integrationstests für den Dienst im Pull-Request-Build ausführen wollen.

E2E oder Integration?

Als ich zum ersten Mal versuchte, diese Änderungen vorzunehmen, fand ich heraus, dass bereits einige Arbeit geleistet wurde, um Integrationstests für einen lokal ausgeführten Dienst auszuführen. In unserer Microservice-Architektur muss jeder Service möglicherweise mehrere unterschiedliche Services aufrufen. Um diese Anrufe zu verspotten und Behauptungen gegen die Anfragen aufzustellen, haben wir WireMock verwendet. Dadurch konnten wir alle unsere externen Dienste herausfiltern und Behauptungen nur gegen den zu testenden Dienst ausführen.

Interessanterweise offenbarte dieser Ansatz gewisse Risse in unserem Testansatz. In Dienst A haben wir mehrere Tests gefunden, die Dienst B anrufen würden, um etwas zu testen, das nichts mit beiden zu tun hat! (Ein Authentifizierungs-Proxy, wie sich herausstellte.) Was also eine Integrationsspezifikation hätte sein sollen, wurde nun zu einer E2E-Spezifikation aufgerüstet, da es sich auf Dienst A, Dienst B und den Authentifizierungs-Proxy stützte.

Um zu erklären, warum dies ein Problem ist, sehen Sie sich die Testpyramide (oder eine Variation davon) unten an.

typische_pyramide-1024x938.jpg

Wenn wir in der Pyramide nach oben steigen, steigen die Testausführungszeiten (oft drastisch) und die Testzuverlässigkeit sinkt. Das bedeutet, dass E2E-Tests die langsamsten und unzuverlässigsten Tests von allen sind. Indem wir die Integrationssuite in eine E2E-Suite umwandelten, hatten wir die Zuverlässigkeit unserer Testsuite und damit ihre Effektivität verringert.

Wann sollte eine E2E-Suite durchgeführt werden?

Das alles soll nicht heißen, dass E2E-Tests keinen Platz in Ihrem Testwerkzeug haben. Sie sind ein sehr nützlicher Vermögenswert, insbesondere für das Unternehmen. Wenn etwas kaputt geht, ist es besser zu sagen „wir haben alles zusammen getestet“ als zu sagen „unsere Komponente funktioniert wie erwartet!“ Dies sind nur allgemeine Erkenntnisse aufgrund unserer Architektur – dies trifft möglicherweise nicht auf Sie zu.

E2E-Suiten können beim Testen der Plattform als Ganzes effektive Werkzeuge sein. Es geht nicht darum, die einzelnen Komponenten zu testen. Aufgrund des großen Umfangs dieser Tests wird oft nicht empfohlen, diese auf jeder Integration auszuführen – wie wir es getan haben. Wenn Sie die gesamte Plattform testen müssen (z. B. bei der Veröffentlichung eines größeren Upgrades oder plattformweiter Änderungen), können sie sehr nützlich sein und Probleme erkennen, bevor sie in die Produktion gelangen.

Fazit

Als Ergebnis dieser Änderungen konnten wir unseren Jenkins-Job entfernen, und ich hoffe, dass wir das Gleiche in naher Zukunft mit vielen, vielen anderen Komponenten tun werden. Wir haben also nicht nur die Tests verständlicher gemacht, sondern auch die Komplexität unserer Infrastruktur reduziert. Stattdessen führen wir alle Integrationstests bei jedem Pull-Request auf Travis durch. Dies bedeutet eine kürzere Feedbackschleife für Entwickler und förderte die Zusammenarbeit zwischen unseren Entwicklern und unseren QA-Ingenieuren.

Bewerten Sie mit jedem neuen Testfall, den Sie schreiben, was Sie testen. Testen Sie nicht die Welt, indem Sie E2E-Spezifikationen schreiben, bei denen ein einfacherer Integrationstest hätte ausreichen können. Achten Sie auf die Trennung von Bedenken, da dies Ihre Testsuite schwierig zu warten und unstabil machen kann.

Und vor allem: weiter testen!

Similar Posts

Leave a Reply

Your email address will not be published.