Simple Science

Hochmoderne Wissenschaft einfach erklärt

# Computerwissenschaften# Software-Entwicklung# Verteiltes, paralleles und Cluster-Computing

Effektive Test-Suiten für Microservices erstellen

Eine Fallstudie zu funktionalen und Lasttests für Mikrodienste-Systeme.

― 10 min Lesedauer


Teststrategien fürTeststrategien fürMicroservicesLasttestansätze.Einblicke in funktionale und
Inhaltsverzeichnis

Mikroservices sind ein beliebter Weg, um Systeme zu bauen, die in der Cloud laufen. In einer Mikroservice-Umgebung arbeitet jeder Teil des Systems für sich, was es einfacher macht, Updates oder neue Features hinzuzufügen. Jeder Mikroservice ist für eine spezifische Aufgabe zuständig, die den Bedürfnissen der Organisation entspricht. Dieser Ansatz hilft, die Teile des Systems separat zu verwalten und ermöglicht es ihnen, bei Bedarf zu wachsen.

Wenn du einen Mikroservice erstellst, musst du dich nicht auf bestimmte Technologien stützen, das heisst, du kannst verschiedene Tools und Plattformen verwenden. Diese Dienste werden jedoch von unterschiedlichen Teams entwickelt und gewartet, auch wenn die Nutzer alles als ein komplettes Produkt sehen.

Es ist wichtig, dass das gesamte System gut zusammenarbeitet, auch wenn die Teile getrennt sind. Wenn Systeme komplexer werden, vor allem wenn sie von verschiedenen Teams gebaut werden, wird es schwierig, sicherzustellen, dass jeder Teil durch Tests abgedeckt ist. Nur wenn jede Funktion getestet ist, können wir sicher sein, dass das System korrekt auf sowohl gute als auch schlechte Eingaben reagiert.

Neben dem Testen, ob jedes Einzelteil korrekt funktioniert, ist es auch wichtig zu prüfen, wie das System mit vielen Nutzern gleichzeitig umgeht. Das nennt man Lasttest und es wird überprüft, wie sich das System unter Druck verhält. Diese Art von Test sollte Hand in Hand mit funktionalen Tests gehen, die prüfen, wie gut das System läuft.

Wir haben festgestellt, dass der Bereich, der sich mit Mikroservices beschäftigt, einen Standard-Satz an Tests vermissen lässt, der für Forschung und Weiterentwicklung in diesem Bereich genutzt werden kann. Um diese Lücke zu schliessen, haben wir eine Fallstudie erstellt, um einen solchen Standard-Testkatalog zu entwickeln.

Unser Hauptziel ist es, einen detaillierten Testkatalog für zwei weit verbreitete Mikroservice-Systeme bereitzustellen. Wir konzentrieren uns dabei besonders auf funktionale Tests, die überprüfen, ob das System korrekt reagiert, und Lasttests, die untersuchen, wie gut es viele Nutzer und Anfragen gleichzeitig verarbeiten kann.

In diesem Artikel stellen wir unsere Testbenchmarks durch eine Fallstudie vor und sprechen über einige Herausforderungen, denen wir dabei begegnet sind. Ausserdem teilen wir hilfreiche Praktiken, die beim Testen dieser Systeme verwendet werden können. Wir haben einen vollständigen Satz von Tests erstellt, der die verschiedenen Teile jedes Mikroservice-Systems abdeckt. Dieser Testkatalog kann Forschern helfen, ihre Arbeit im Bereich Mikroservice-Testing zu validieren.

Der Rest dieses Artikels ist wie folgt organisiert: im nächsten Abschnitt gibt's Hintergrundinformationen zu Mikroservices und den verwendeten Testtools. Der folgende Abschnitt behandelt unsere Fallstudie, und danach präsentieren wir die Benchmarks. Am Ende schliessen wir den Artikel ab.

Hintergrund

Funktionale Tests stellen sicher, dass die verschiedenen Funktionen eines Systems so arbeiten, wie es erwartet wird. Testfälle werden oft basierend auf den System-Spezifikationen erstellt, wobei jeder Test einem spezifischen Bedarf oder einer Funktion entspricht. So wird sichergestellt, dass jeder Teil der Software unabhängig funktioniert, wie es beabsichtigt ist.

Beim Testen von Mikroservices behandeln wir das System wie eine Black Box. Das bedeutet, wir konzentrieren uns darauf, was die Nutzer auf ihren Bildschirmen sehen, ohne uns darum zu kümmern, wie alles zusammengebaut ist. Verschiedene Tools und Frameworks helfen beim Schreiben von Testskripten. Zum Beispiel hilft das Selenium-Framework beim Testen von Webanwendungen, indem es Webbrowser automatisiert, um Nutzerinteraktionen zu simulieren.

Funktionale Regressionstests sind ein weiterer wichtiger Aspekt. Sie überprüfen, ob das System nach Änderungen weiterhin korrekt funktioniert. Das ist entscheidend für die Qualitätssicherung, da es hilft, unbeabsichtigte Änderungen zu erkennen, die die Systemleistung beeinträchtigen könnten.

Ein weiterer wichtiger Testtyp ist der Lasttest. Dieser prüft, wie gut das System mit verschiedenen Nachfragen umgehen kann. Die Last bezieht sich auf die Anzahl der Nutzer und Anfragen, die das System bewältigen muss. Lasttests zeigen, wie sich das System unter Druck verhält und können Schwächen oder Verbesserungsbereiche aufdecken.

Es gibt verschiedene Möglichkeiten, Lasttests durchzuführen, zum Beispiel mit echten Nutzern, automatisierten Lasttreibern oder spezialisierten Testplattformen. Zu analysieren, wie ein System auf unterschiedliche Lasten reagiert, kann zeigen, wo Verbesserungen möglich sind, da einige Probleme erst unter bestimmten Lastbedingungen sichtbar werden.

Ähnlich wie beim funktionalen Testen gibt es Frameworks, die helfen, Lasttests zu automatisieren. Zum Beispiel kann Gatling Lasttests durchführen und Berichte über die Systemleistung unter Druck erstellen.

Testabdeckung ist ein weiteres wichtiges Mass im Software-Testen. Sie zeigt uns, wie viel des Systems getestet wurde und zeigt, welche Teile während der Tests bearbeitet wurden, im Vergleich zum gesamten System.

Benchmarks für Mikroservice-Systeme

Um zu demonstrieren, wie funktionale und Lasttests für Mikroservices funktionieren, haben wir zwei bekannte Systeme für unsere Fallstudie ausgewählt, die eine Vielzahl von Funktionen bieten. Das erste ist Train-Ticket, ein System zur Buchung von Zugtickets, das in Java erstellt wurde, und das zweite ist eShopOnContainers, das für Online-Shopping-Anwendungen mit .NET konzipiert ist.

Das Train-Ticket-System besteht aus 47 Mikroservices. Die Architektur von Train-Ticket beschreibt, wie das Frontend, das Überwachungssystem und verschiedene Dienste miteinander interagieren. Dieses Setup zu verstehen, hilft, wie jeder Mikroservice verbunden ist.

Es gibt verschiedene Nutzeraktionen innerhalb von Train-Ticket, wie das Suchen nach einem Zug, das Buchen eines Tickets, das Aktualisieren einer Reservierung, das Bezahlen eines Tickets, das Abholen und das Betreten eines Bahnhofs. Admin-Aktionen beinhalten das Verwalten von Bestellungen, Routen, Reiseplänen und Nutzerinformationen.

Für unsere Fallstudie haben wir die neueste Version von Train-Ticket verwendet. Dieses System wurde von einem Uni-Team entwickelt, um als Benchmarking-Tool für die Ticketbuchung zu dienen.

Das eShopOnContainers-System ist als Referenzanwendung für .NET Core konzipiert. Es teilt sein Frontend zwischen einer traditionellen Webanwendung und einer Single-Page-Anwendung. Dieses System umfasst verschiedene Anwendungsfälle für Online-Shopping, wie das Einloggen, das Hinzufügen von Artikeln zum Warenkorb, das Auschecken und das Überprüfen vergangener Bestellungen.

In unserer Fallstudie haben wir die aktuellste Version von eShopOnContainers verwendet, das auch von einer grossen Community unterstützt wird, die zum Code beisteuert.

Fallstudie

Das Ziel unserer Fallstudie ist es, ein umfassendes Set an Tests für alle Systemendpunkte zu erstellen. Wir konzentrieren uns darauf, die Reaktionsfähigkeit und Funktionalität der Mikroservice-Systeme unter Druck zu bewerten.

Funktionale Tests sehen das System als Black Box und berücksichtigen nicht, wie es intern aufgebaut ist. Sie spiegeln das Nutzererlebnis wider, indem sie Nutzeroberflächeninteraktionen testen, um Genauigkeit und Konsistenz sicherzustellen.

Lasttests zielen darauf ab, Engpässe und Leistungsprobleme innerhalb des Systems zu identifizieren. Sie überprüfen, wie gut die Mikroservices unter unterschiedlichen Lasten abschneiden, was die Zufriedenheit der Nutzer erheblich beeinflussen kann.

Während unserer Tests sind wir auf mehrere Herausforderungen gestossen. Wir werden Best Practices und Lösungen zu häufigen Problemen teilen, während wir unsere Ergebnisse präsentieren.

Fallstudie zu funktionalen Regressionstests

Um sicherzustellen, dass das Mikroservice-System korrekt funktioniert, haben wir einen automatisierten, webbasierten Testkatalog mit Selenium implementiert. Unser Ziel war es, zu überprüfen, dass alle Mikroservices in verschiedenen Browsern wie erwartet funktionieren.

Wir haben manuell eine detaillierte Liste aller potenziellen Nutzeraktionen innerhalb der Mikroservices erstellt und unseren Fortschritt bei der Durchführung dieser Tests in einer Tabelle verfolgt. Das hat uns geholfen, organisiert zu bleiben und eine vollständige Testabdeckung sicherzustellen.

Anfangs haben wir versucht, Katalon Web Recorder für die Testerstellung zu verwenden, aber festgestellt, dass es zu unordentlichem Code führte. Stattdessen haben wir unsere eigenen Selenium-Skripte geschrieben, die als JUnit-Tests laufen können. Zunächst haben wir den Chrome-Browser für Tests verwendet, da wir so sehen konnten, wie alles funktionierte und leicht debuggen konnten.

Als wir unsere Tests erweiterten, wechselten wir zum HTML Unit WebDriver, der keine grafische Benutzeroberfläche hat. Dieser Wechsel beschleunigte unseren Testprozess. Wir führten auch das TestNG-Framework ein, um die parallele Ausführung von Tests zu ermöglichen, was die benötigte Zeit für die Ausführung erheblich reduzierte.

Studienergebnisse

Durch unsere funktionalen Regressionstests wollten wir jede mögliche Nutzerfunktionalität innerhalb der Systeme testen. Wir haben erfolgreich 51 Anwendungsfälle für das Train-Ticket-System und 26 für eShopOnContainers getestet.

Allerdings konnten wir einen Anwendungsfall, der mit dem Konsignationsdienst in Train-Ticket zusammenhing, aufgrund von Bereitstellungsproblemen nicht vollständig testen. Dennoch deckten die durchgeführten Tests alle clientseitigen Anwendungsfälle im Zusammenhang mit der Buchung von Tickets ab.

Im eShopOnContainers-System haben wir Tests für verschiedene Nutzeraktionen durchgeführt, einschliesslich Einloggen, Browsen, Artikel in den Warenkorb legen und Auschecken. Wir haben ähnliche Anwendungsfälle gruppiert, um einen effizienteren Testprozess zu schaffen.

Lasttests

Für die Lasttests konzentrierten wir uns darauf, wie verschiedene Endpunkte in den Mikroservice-Systemen auf unterschiedliche Nutzerlasten reagierten. Ziel war es, Einblicke zu geben, wie viele Nutzer die Systeme gleichzeitig unterstützen könnten und Probleme zu identifizieren, die unter Druck auftreten.

Wir notierten die spezifischen Hardwarekonfigurationen, die für die Tests verwendet wurden, und hielten die Leistung jedes Endpunkts fest. Dazu gehörten Details zu den beteiligten Mikroservices, den entsprechenden Tests und ob sie ausreichend abgedeckt waren.

Wir schrieben alle Lasttests manuell, um einen fokussierten und klaren Testcode sicherzustellen. Eine Herausforderung war das Verwalten der Benutzerautorisierung in den Tests. Wir überwanden dies, indem wir Authentifizierungstokens in unseren Tests speicherten, um einen gültigen Zugriff auf die Endpunkte zu gewährleisten.

Um Eingaben für Formulare in Anfragen bereitzustellen, verwendeten wir zwei Hauptmethoden: die Funktion formparam für einfache Parameter und RawFileBody für grössere Anfragen, was half, Daten effizienter in Tests zu verwalten.

Studienergebnisse

Die Ergebnisse unserer Lasttests zeigten unterschiedliche Leistungen basierend auf der Nutzerlast. Jedes Ladeszenario musste genau getestet werden, insbesondere unter verschiedenen Serverbedingungen.

In unseren Tests für das Train-Ticket-System identifizierten wir insgesamt 240 Endpunkte. Allerdings hatten nur 41 davon funktionale Endpunkte. Unsere Tests zielten darauf ab, alle ausreichend abzudecken.

Für jeden Anwendungsfall massen wir die Reaktionszeiten und notierten, wie viele Anfragen 800 ms überschritten. Diese Kennzahl half uns zu bestimmen, wie gut die Systeme unter spezifischen Lastszenarien abschnitten.

Ähnlich verfolgten wir für das eShopOnContainers-System die Leistung über mehrere Anwendungsfälle. Wir stellten fest, dass das System bei niedrigen Lasten gut zurechtkam, aber Schwierigkeiten hatte, als die Anzahl der Nutzer erheblich anstieg.

Vorgeschlagener Benchmark

Aus unserer Fallstudie haben wir einen Testbenchmark für die Mikroservice-Systeme erstellt. Dieser Benchmark dient der Community als Orientierung, wie ähnliche Systeme auf verschiedene Arten von Tests und Lasten reagieren.

Der Benchmark ist wichtig, um wiederholbare Tests zu etablieren, auf die sich andere beziehen können. Er kann helfen, die Leistung verschiedener Systeme im Laufe der Zeit zu vergleichen und Einblicke in deren Entwicklung zu geben.

Wir haben uns während unserer Tests auf realistische Lasten konzentriert, beginnend mit 100 Nutzern bis hin zu 5.000 Nutzern. Dieser Bereich half, ein besseres Verständnis der normalen Arbeitslast zu entwickeln, die die Systeme bewältigen können.

Geschwindigkeit und Konsistenz waren Schlüsselkomponenten unserer Tests. Wir massen jede Reaktionszeit und behielten im Auge, welche unter oder über unserem Zielwert lagen. Wir haben entschieden, dass ein System eine bestimmte Last bewältigen kann, solange weniger als 20 % der Anforderungen länger als 800 ms benötigen.

Indem wir unsere Tests basierend auf Mikroservices gruppierten, stellten wir sicher, dass jeder Test viele Aussagen über die Systemleistung und -funktionalität beinhaltete. Der Erfolg eines Tests hing davon ab, ob alle Aussagen insgesamt bestanden oder fehlgeschlagen sind.

Sobald wir unsere Tests abgeschlossen hatten, teilten wir unsere Erkenntnisse mit der Community, damit andere auf unserer Arbeit aufbauen und die Testpraktiken für Mikroservice-Systeme erweitern können.

Die Hauptbeiträge unserer Arbeit sind doppelt. Erstens haben wir ein Open-Source-Beispiel für automatisierte Tests von Mikroservice-Systemen bereitgestellt. Zweitens haben wir einen robusten anfänglichen Benchmark entwickelt, den andere nutzen können, um ähnliche Systeme in Zukunft zu bewerten.

Mehr von den Autoren

Ähnliche Artikel