08. April 2022

Software Testing: Ein Hands-on Guide

Autor*in: Knarik Hovhannisyan, Software testing Engineer

In diesem Artikel gebe ich eine allgemeine Einführung in das Thema Testing, erläutere seine Bedeutung für die Softwareentwicklung und stelle einige Testarten vor. Testing ist essenziell, weil wir alle Fehler machen. Manche dieser Fehler sind unbedeutend, andere können teuer für ein Unternehmen oder sogar lebensbedrohlich sein (wie im Beispiel der Ariane 5 im Jahr 1996). Das macht deutlich: Webprojekte sollten niemals ohne Tests auskommen. Wir müssen alles testen, was wir entwickeln, denn es kann immer etwas schiefgehen. Im besten Fall passiert nichts Gravierendes – aber es kann auch dazu kommen, dass Software schlicht unbrauchbar ist oder sogar Nutzer:innen gefährdet.

Image showing a hot air balloon repaired with patches of different colors in order to not lose any air, illustrated in the factorial colors

Was ist Softwaretesting überhaupt?

Softwaretesting ist eine Tätigkeit, die Risiken reduziert und die Qualität verbessert, indem sie Defekte, Fehler und Lücken aufdeckt. Es ist eine Methode, um zu überprüfen, ob das tatsächliche Softwareprodukt den erwarteten Anforderungen entspricht. Das bedeutet, fehlende Anforderungen im Vergleich zu den tatsächlichen Anforderungen zu identifizieren. Testing ist ein Bestandteil des gesamten Qualitätssicherungsprozesses (QA), der sicherstellen soll, dass Systeme ohne Fehler in Betrieb gehen, die den erfolgreichen Start eines Webprojekts verhindern könnten.

Warum ist Software Testing so wichtig?

Software Testing trägt maßgeblich zum Erfolg jedes Projekts bei. Hier einige Argumente, die seine Relevanz verdeutlichen:

Fehlerbehebung: Testing hilft, Defekte und Bugs zu entdecken, bevor sie an die Kundschaft ausgeliefert werden.

Sicherheit: Menschen suchen nach vertrauenswürdigen Produkten. Mit Testing lässt sich der Sicherheitsaspekt überprüfen.

Qualität: Testing steigert die Gesamtqualität des Systems.

Zuverlässigkeit: Testing macht Software zuverlässiger und einfacher zu bedienen.

Kosteneffizienz: Wenn Defekte frühzeitig entdeckt und behoben werden, lassen sich unerwartete Kosten vermeiden, die sonst erst am Ende des Projekts oder sogar erst im laufenden Betrieb entstehen würden.

Testarten: Funktionale vs Nicht-funktionale Tests

Tests werden von QA Engineers durchgeführt – manuell oder automatisiert, je nach Projektanforderungen und weiteren Rahmenbedingungen. Es gibt viele verschiedene Testarten, die sich in funktionale und nicht-funktionale Tests unterteilen lassen. Funktionale Tests beschreiben, was das Produkt tut, während nicht-funktionale Tests beschreiben, wie das Produkt funktioniert. Erstere überprüfen jede Funktion bzw. jedes Feature der Software, Letztere überprüfen nicht-funktionale Aspekte wie Performance, Usability und Zuverlässigkeit. Nicht-funktionale Tests lassen sich manchmal nur schwer manuell durchführen. Hier einige Beispiele für beide Kategorien.

Funktionale Tests

Unit-Tests – Beim Unit-Testing werden kleine Codeabschnitte überprüft, um sicherzustellen, dass die einzelnen Bestandteile eines Programms für sich genommen korrekt funktionieren. Unit-Tests validieren die Funktion einer Einheit – anders gesagt: ob der Code das tut, wofür er entwickelt wurde. Diese Art von Tests wird meist von Entwickler:innen selbst durchgeführt.

Integrationstests – Integrationstests überprüfen, ob einzelne Codemodule als Gruppe korrekt zusammenarbeiten. Ziel ist es, Fehler im Zusammenspiel von Softwaremodulen aufzudecken, sobald diese integriert werden. Integrationstests werden etwa eingesetzt, um das Zusammenspiel mehrerer Funktionen zu prüfen, etwa Produktauswahl, Warenkorb, Checkout und Kaufabwicklung.

Smoke-Tests – Diese Testart soll sicherstellen, ob ein bereitgestellter Software-Build stabil ist. Dabei wird ein minimaler Satz an Tests auf dem initialen Build ausgeführt, um zu prüfen, ob die kritischen Funktionen des Programms funktionieren.

Regressionstests – Ziel von Regressionstests ist es zu prüfen, ob Codeänderungen bestehende Funktionen beeinträchtigt haben, da neue Codeänderungen manchmal unerwünschte Nebeneffekte auf bestehende Funktionalitäten haben. Diese Tests stellen sicher, dass der alte Code auch nach Ausführung neuer Codeänderungen weiterhin funktioniert.

Sanity-Tests – Eine Unterart der Regressionstests. Sie überprüfen neue Funktionalität wie Bugfixes und stellen sicher, dass durch diese Änderungen keine weiteren Probleme entstanden sind.

User Acceptance Testing (UAT) – Diese Tests werden in der Regel von den Endnutzer:innen oder der Kundschaft durchgeführt, um die Software vor dem Produktivgang abzunehmen bzw. zu verifizieren. UAT bestimmt, ob die Software auslieferungsfähig ist. Alpha- und Beta-Tests sind zwei Beispiele für User Acceptance Testing: Alpha-Tests werden von einem internen Team beim Entwicklungsunternehmen durchgeführt, bevor die Software veröffentlicht wird, während Beta-Tests extern von Personen außerhalb des Entwicklungsunternehmens durchgeführt werden (etwa von Kund:innen oder Kundengruppen).

Nicht-funktionale Tests

Performance-Tests – Dieser Testprozess dient der Überprüfung von Geschwindigkeit, Antwortzeit, Stabilität, Zuverlässigkeit, Skalierbarkeit und Ressourcennutzung. Mit Performance-Tests wird geprüft, wie sich ein System unter einer bestimmten Last verhält. Es gibt zahlreiche Tools für Performance-Tests, etwa Apache JMeter, WebLOAD, LoadNinja oder Loadero. Alle diese Tools lassen sich auch für Last- und Stresstests einsetzen.

Lasttests (Load Tests) – Lasttests lassen sich als Unterart der Performance-Tests betrachten. Sie prüfen, wie Systeme funktionieren, wenn eine große Anzahl virtueller Nutzer:innen gleichzeitig über einen bestimmten Zeitraum Aktionen ausführt. Ziel ist es zu ermitteln, wie viele Nutzer:innen das System tatsächlich verarbeiten kann. Lasttests zeigen, wie sich ein System unter einer erwarteten Last verhält. Ein Beispiel wäre das gleichzeitige Ausführen zahlreicher Anwendungen auf einem Server oder Computer.

Stresstests – Eine weitere Unterart der Performance-Tests, die die Obergrenzen eines Systems unter extremer Last prüft. Dabei wird untersucht, wo die Kapazitätsgrenzen des Systems liegen, wenn die Last über das erwartete Maximum hinausgeht, und wie sich das System nach Rückkehr zur Normalauslastung wieder erholt. Ein Beispiel für Stresstests wäre eine E-Commerce-Anwendung an einem großen Verkaufstag mit einer enormen Anzahl gleichzeitiger Besucher:innen.

Volumentests (Volume Tests) – Dieser nicht-funktionale Test analysiert die Performance eines Systems bei steigendem Datenvolumen in der Datenbank. Volumentests prüfen, ob das System bei einem bestimmten Datenvolumen wie erwartet reagiert – etwa auch bei wachsender Dateigröße. Ein Beispiel: Ein Finanzunternehmen erzeugt aktuell xx GB an Daten, in zwei Jahren wird ein Anstieg auf xx × 10 GB erwartet und in fünf Jahren auf xx × 50 GB. Volumentests sind hier nötig, um zu prüfen, ob das System diesen Prognosen standhält.

Usability-Tests – Usability-Tests messen, wie einfach und benutzerfreundlich eine Softwareanwendung ist. Eine kleine Gruppe von Ziel-Endnutzer:innen verwendet die Anwendung, um Usability-Schwachstellen aufzudecken. Dabei wird gemessen, wie „intuitiv“ Nutzer:innen mit der Anwendung interagieren, wie flexibel die Anwendung im Umgang mit Bedienelementen ist und wie gut sie ihre Ziele erfüllt.

Testing kann in unterschiedlichen Phasen des Softwareentwicklungszyklus stattfinden, abhängig vom gewählten Vorgehensmodell. Beim Wasserfallmodell etwa beginnt das Testing erst nach Abschluss der Entwicklungsphase – dieses Modell eignet sich vor allem für Projekte mit klaren, selten wechselnden Anforderungen. Im agilen Modell dagegen hat jede Iteration ihre eigene Testphase, und Regressionstests werden bei jeder neuen Funktionsveröffentlichung erneut durchgeführt. Zudem sollte vor dem Deployment auf die nächste Instanz in einer geeigneten Umgebung getestet werden (etwa QA oder Entwicklung), und nach dem Deployment sind Smoke- oder Wartungstests auf der bereitgestellten Instanz erforderlich.

Wann sollte man mit dem Testen aufhören?

Eines der wichtigsten Testprinzipien lautet: Vollständiges Testen ist unmöglich. Es lassen sich zwar kleine Softwarekomponenten erschöpfend testen und dabei alle möglichen Datenkombinationen abdecken – bei einem gesamten System ist das jedoch nicht praktikabel. Zwei zentrale Aspekte sind dabei zu beachten.

Der wichtigste Aspekt ist die Priorisierung, die dabei hilft, mit einer endlichen und begrenzten Menge an Tests ein akzeptables Ergebnis zu erzielen. Die wichtigsten Tests sollten zuerst durchgeführt werden – also die für das System bedeutsamsten Aspekte. Das betrifft die Funktionen mit der höchsten Relevanz sowie das wichtigste nicht-funktionale Verhalten, mit dem sich die größten Risiken adressieren lassen.

Der nächste zu berücksichtigende Aspekt sind die Abschlusskriterien. Ihr Zweck ist es zu verhindern, dass eine Aufgabe als abgeschlossen gilt, obwohl noch offene Teilaufgaben bestehen. Sie legen objektive Kriterien fest, anhand derer sich beurteilen lässt, ob es sicher ist, das Testen zu beenden.

Fazit

Zusammenfassend lässt sich sagen: Softwaretesting ist aus den oben genannten Gründen eine essenzielle Phase in jedem Webprojekt. Es gibt noch viele weitere Testarten, die in diesem Artikel nicht behandelt wurden – in der Regel werden sie passend zu den jeweiligen Projektanforderungen ausgewählt. Und nicht vergessen: Jedes Teammitglied und die Zusammenarbeit im Team steigern die Qualität eines Projekts. Das bedeutet, jeder Test, den man in den Projektverlauf einbaut, trägt dazu bei, am Ende ein besseres Produkt zu liefern.

FAQ