Africa Studio - stock.adobe.com

Passende Testmethoden für die Softwareentwicklung finden

Viele Unternehmen möchten mehr automatisierte Tests durchführen, aber welche Tests eignen sich für welche Probleme? Hier finden Sie eine Antwort auf diese Frage.

Dem Hexagonal-Architekturmodell für Softwaretests von Alistair Cockburn liegen drei zentrale Konzepte zugrunde: Erstens der Kerncode, zweitens die Adapter, die es diesem Code ermöglichen, mit der Außenwelt zu arbeiten, und drittens die externen Systeme, mit denen der Code interagiert.

Zum Beispiel kann ein kleines Snippet Website-Code entscheiden, ob ein Passwort gültig ist. Dieses Snippet kann isoliert und für sich allein aufgerufen werden. Andere Teile dieser Software könnten mit einer Datenbank, einer REST API oder einem Webbrowser interagieren. Wir könnten jedes Stück Code isolieren und einzeln ausführen – allerdings nutzen wir dann die Software nicht als ein Gesamtsystem.

Für die Herangehensweise an dieses Softwaretestmodell gibt es drei Möglichkeiten:

  • Stellen Sie sich die isolierten Snippets als einzelne Punkte in der Kernanwendung vor.

  • Testen Sie den ganzen Weg bis zum Adapter und fälschen Sie dann den Adapter mit einem Mock, Stub oder Spion. Wir könnten unseren Code testen, indem wir nur ein einziges reales externes Objekt aufrufen – ein Dateisystem, eine API oder eine Datenbank.

  • Wir könnten das gesamte System als ein System ansehen und eine echte Datenbank oder einen echten Webbrowser nutzen.

Tests mit einem größeren Umfang sind zwar leistungsfähiger, aber die Koordination, Erstellung, Ausführung und Wartung wird teuer. Tests auf höherer Ebene werden auch immer langsamer ausgeführt. Wenn sie fehlschlagen, kann es einige Zeit dauern, bis man genau herausfinden kann, was schiefgelaufen ist.

Einfach ausgedrückt sind Tests auf höherer Ebene leistungsfähiger – aber auch schmerzhafter. Als Mike Cohn das Konzept der Testautomatisierungspyramide vorstellte, schlug er vor, dass Teams weniger automatisieren sollten. Er setzte Systemtests an die Spitze, aber er definierte kein Gefälle der Pyramide. Ein Team muss einiges für sich selbst regeln.

Hier finden Sie einige Ideen, wie Sie die verschiedenen Softwaretestmethoden einsetzen – und wie sie Ihnen helfen.

Unit-Tests

Der kleinste Codeausschnitt, der isoliert laufen kann, kann als Unit (Einheit) bezeichnet werden. Eine echte Unit interagiert mit nichts anderem. In modernen Programmiersprachen wäre das ein Unterprogramm oder eine Funktion oder Methode.

Bis Tools wie JUnit aufkamen, wurden Unit-Tests oft mit Debugging vermischt. Ein Programmierer konnte einen Haltepunkt für ein Stück Code festlegen, die Variablen erstellen und das Programm bis zu diesem Haltepunkt laufen lassen, wobei es jede Codezeile durchschritt. Entwickler haben dies aber nur selten getan, und stattdessen auf einer höheren Ebene getestet. Unit-getesteter Code weist im Allgemeinen mehr Fehler auf – und Änderungen am Code führen zu noch mehr neuen Fehlern.

Unit-Tests sind leicht zu schreiben, schnell auszuführen und relativ einfach zu warten. Moderne Programmierer schreiben jedoch selten solch vollständig isolierten Code. Stattdessen interagiert der Code so gut wie immer mit etwas anderem – wie einem Dateisystem oder dem Netzwerk oder einer Datenbank. Um echte Unit-Tests durchzuführen, stoppt der Programmierer solche Verbindungen.

In diesem Fall kann der Unit-Test sicherstellen, dass die Software einen bestimmten Befehl an die Datenbank sendet oder das Ergebnis einer Datenbankabfrage auf eine bestimmte Art und Weise verarbeitet.

In seinem Buch Working Effectively with Legacy-Code schreibt Michael Feathers, dass ein Test kein Unit-Test ist, wenn:

  • er mit der Datenbank interagiert;
  • er über das Netzwerk kommuniziert;
  • er das Dateisystem nutzt;
  • er nicht gleichzeitig mit einem Ihrer anderen Unit-Tests ausgeführt werden kann;
  • Sie Ihre Umgebung anpassen müssen (zum Beispiel Konfigurationsdateien bearbeiten), um ihn auszuführen.

Im Folgenden beschreiben wir Tests, die eine Verbindung über diese externen Grenzen hinweg herstellen, als Integrationstests.

Integrationstests

In der hexagonalen Architektur läuft ein Integrationstest – auch: Interaktionstest – von einem Punkt in der Mitte bis zu einem Adapter. Von dort wird eine Verbindung zu einem realen System hergestellt, zum Beispiel durch Aufruf einer API oder durch das Schreiben von Dateien auf die Festplatte. Dies kann sogar innerhalb eines Webbrowsers ablaufen – allerdings unter Verwendung statischer Dateien und ohne Verbindung zum Internet. Oder der Test kann Dateien aus dem Internet abrufen und den Text direkt interpretieren und nicht mit einem Webbrowser interagieren.

Beim Integrationstest geht es darum, eine reale Komponente zu verwenden. Dies kann allerdings Probleme verursachen. Wenn das System eine Verbindung zu einer Datenbank herstellt und die Datenbank sich ändert, dann kann der Test fehlschlagen – und sei es auch nur aus technischen Gründen. Denken Sie an den Fall, dass der Test die Datenbank für die heutigen Transaktionen abfragen soll. Diese Art von Test erfordert eine umfangreiche Einrichtung auf der Testdatenbank. Eine andere Möglichkeit ist die Simulation des Aufrufs mittels Service-Virtualisierung.

Integrationstests sind in der Regel relativ schnell und decken eine größere Menge an Code ab als Unit-Tests. Sie sind oft einfach zu debuggen, und sie können parallel ausgeführt werden. In vielen Fällen ist die Integration der Sweet Spot für automatisierte Prüfungen.

System-, UI- und End-to-End-Tests

End-to-End-Tests durchlaufen in der hexagonalen Architektur das gesamte System – von der Benutzeroberfläche über die Datenbank bis hin zur Auftragsbearbeitung und -erfüllung. Als solche können sie eine Menge Funktionalität schnell ausführen und überprüfen.

End-to-End-Tests laufen über die gesamte Benutzerschnittstelle (UI). Wenn sich auf der Ebene der Benutzeroberfläche etwas ändert, läuft ein grafischer Test Gefahr, einen falschen Fehler zu markieren. Die Summe dieser Risiken führt im Laufe der Zeit zu einem höheren Wartungsaufwand.

Programmierer müssen der Anwendung unter Umständen Testability Hooks hinzufügen. Das Hinzufügen von UI-Tests kann mit der Zeit teuer werden.

Ein Ansatz zum Aufteilen von UI-Tests ist die DOM-to-Database-Technik. Die von Titus Fortner von Sauce Labs populär gemachten DOM-to-Database-Tests führen einen Teil der Funktionalität aus. Diese Tests sind schnell zu schreiben, flott auszuführen und veralten selten.

Die Tests stellen sicher, dass die Software das macht, was der Programmierer erwartet. Sie können allerdings nicht mit dem Fall umgehen, dass der Programmierer die Anforderung missversteht. Diese Tests helfen auch nicht in Fällen, in denen niemand darüber nachdenkt, wie die Software mit bestimmten Situationen umgehen soll. Um dieses Risiko zu verringern, sollten Sie sich den Einsatz von Akzeptanztests überlegen.

Akzeptanztests

Akzeptanztests – oder auch Abnahmetests, Verfahrenstest, User Acceptance Test – sollten Sie als das absolut notwendige Minimum betrachten, damit die Software funktioniert. Software, die einen Akzeptanztest besteht, funktioniert nicht unbedingt. Aber ein fehlgeschlagener Akzeptanztest bedeutet definitiv, dass die Software nicht richtig arbeitet.

In der agilen Softwareentwicklung definiert ein Projektteam, was Akzeptanz bedeutet, bevor die Programmierer Code schreiben. Echte, funktionierende Beispiele zu haben ist in der Softwareentwicklung ähnlich, wie Quizfragen zu einem Thema zu beantworten, bevor man ein entsprechendes Lehrbuch liest. Der Ansatz der Akzeptanztests erlaubt es den Programmierern zu diskutieren, was die Software tun soll. Er verhindert ganze Paletten an Missverständnissen, die zu Fehlern im Produkt führen.

Akzeptanztests kreuzen mindestens zwei Seiten des Sechsecks. Sie können oft in einfacher Sprache und im Stil einer Checkliste geschrieben werden. Cucumber ist ein beliebtes Open-Source-Framework, um Akzeptanztests in automatisierte Prüfungen zu verwandeln. SpecFlow leistet ähnliche Arbeit für .NET-Software. Das Problem dabei ist, dass Teams manchmal System- oder End-to-End-Tests mit mehreren Komplexitätsebenen erstellen.

Der Wert von Akzeptanztests liegt im Gespräch. Wenn diese Diskussionen nicht stattfinden, wird die Automatisierung wahrscheinlich die Konversation und das gemeinsame Verständnis einschränken.

Leistungstests

Einfache Leistungs- oder Performance-Tests können so einfach sein wie die Wiederverwendung von UI-Tests und deren zeitliche Planung. Wenn eine Operation zu lange dauert, senden sie einen Alarm aus.

Lasttests prüfen im Allgemeinen die Systemreaktion, wenn die Anzahl der Benutzer steigt. Wie Sicherheitstests sind Leistungstests eine Softwaretestmethode, die früher am Ende eines Projekts durchgeführt wurde.

Leistungstests sind nützlich, weil sie kontinuierlich stattfinden – oder zumindest häufig genug, um die Kosten in der Cloud vorherzusagen. Führen Sie das Tool einen Tag lang in der Cloud mit einer Anzahl täglicher Benutzer aus. Wenn Ihr Zeitmodell für die Verwendung der Anwendung korrekt ist, können Sie die Cloud-Kosten der Anwendung pro Tag ermitteln.

Sicherheitstests

Menschen verwenden häufig Werkzeuge, um Penetrationstests zu beschleunigen. Diese Tools wie zum Beispiel Nmap, Advanced IP Scanner und Advanced Port Scanner scannen ein ganzes Netzwerk, um offene Ports und Gerätesignaturen zu finden. Sobald Sie über eine Liste von IP-Adressen und offenen Ports und Systemen verfügen, können andere Tools in Ihrem Testarsenal versuchen, Schwachstellen aufzuspüren. In diesem Sinne sind Penetrationstests in hohem Maße automatisiert.

Testen, aber zuerst reden

Bei den ganzen Tests darf der menschliche Faktor nicht unter den Tisch fallen. Die Fähigkeit, Tests zu entwerfen, diese auszuführen, über die Ergebnisse zu berichten, aus den Erfahrungen zu lernen und die Strategie in Echtzeit anzupassen, während man zwischen den Aktivitäten wechselt – das alles ist einzigartig menschlich.

Ein herkömmlicher automatisierter Test ist ein Test, wenn er zum ersten Mal ausgeführt wird. Danach wird dieser Test, strenggenommen, zur Änderungserkennung.

Dennoch möchten die meisten Teams mehr mit Testwerkzeugen arbeiten. Aber wo? Und wovon machen Sie weniger, um mehr von etwas anderem zu machen? Bei einer Scrum-Kadenz kann ein Team damit einverstanden sein, mit der Automatisierung einer neuen Art von Prüfung zu experimentieren, zumindest für eine oder zwei Wochen. Scrum gibt Teams die Werkzeuge an die Hand, um diese Art von Experimenten zu erstellen und zu messen.

Analysieren Sie, welche Softwaretestmethoden für Ihre speziellen Projekte angebracht sind. Stellen Sie eine Hypothese auf, wie man besser testen kann. Und experimentieren Sie dann ein oder zwei Sprints damit.

Erfahren Sie mehr über Softwareentwicklung