Softwaretesting ist eine essenzielle Support-Funktion einer jeden digitalen Produktentwicklung. Es ist eine Verantwortlichkeit, die von Allen im Produkt- und Projektteam geteilt wird, mit unterschiedlicher Ausprägung je nach Fachgebiet.

Unsere Erfahrung zeigt, dass im Entwicklungsprozess häufig zu spät damit begonnen, oder es nicht systematisch und professionell betrieben wird. Das führt schnell zu Qualitäts-problemen, die sich in verspäteter Auslieferung, Verlangsamung der Entwicklung und schwerwiegenden Fehlern bei den Anwendern manifestieren.

Wir möchten Ihnen in diesem Blogbeitrag einen Überblick geben, was professionelles Softwaretesting tatsächlich bedeutet und was es erfordert.

1. Grundsätzliches zum Thema Softwaretesting

Bei der Entwicklung und Bereitstellung von Software basierten Produkten und Services erfolgt die Testung auf verschiedenen Ebenen: einzelne Module, Komponenten, einem Teilverbund aus Komponenten und dem Gesamtsystem. Unabhängig von der Ebene, auf der die Testung erfolgt, müssen verschiedene Ziele wie Korrektheit, Performanz und Sicherheit gleichermaßen berücksichtigt werden. Weitere wichtige Aspekte bei der Testung sind die Testmethode und die Ausführungsart. Neben Methode, Ausführung, Ebene und Ziel eines Tests ist es wichtig, die richtigen Voraussetzungen für die Testung zu schaffen. Hierzu ist eine rein technische Lösung nicht ausreichend. Im Unternehmen muss eine entsprechende Test Kultur eingeführt und befördert werden. Im Folgenden werden Ebenen, Ziele und die Voraussetzungen näher erläutert.

2. Voraussetzungen für ein erfolgreiches Softwaretesting

Testung kann nur dann zu den propagierten Erfolgen führen, wenn auch die Umgebung auf Testung ausgerichtet ist. Wesentliche Faktoren sind hierbei die Einbettung des Softwaretestings in eine Qualitätsmanagement-Strategie, die Unternehmenskultur und die Architektur des zu testenden Systems.

a. Qualitätsmanagement

Man kann Qualität nicht in ein Produkt „hineinprüfen“. Testung ist ein Element der Qualitätssicherung und dient dazu festzustellen, ob ein Produkt die gewünschte und zuvor definierte Qualität aufweist. Testung und Testautomatisierung müssen also in ein übergeordnetes Qualitätsmanagement eingebettet werden. Die Ausgestaltung der Testung orientiert sich dann an den dort definierten Qualitätszielen.

b. Kultur

Der Versuch, Softwareprojekte nach klassischen Ansätzen zu führen, ist in der Geschichte der Softwareentwicklung immer wieder gescheitert. Hieraus entstanden agile Methoden und die Erkenntnis, dass Testung in den Arbeitsalltag der Softwareentwicklung integriert werden muss. Eine der Entwicklung nachgelagerte Testung, wie sie in den Wasserfall- oder V-Modell Prozessen vorgesehen ist, führt zu langen Feedbackschleifen und Missverständnissen durch Informationsverlust bei Übergaben. Wenn sich Definition und Entwicklung von Tests in den Aufgabenbereich des Entwicklers verlagern, entstehen bei traditionell aufgestellten Organisationen verschiedene Probleme. Entwickler klagen über geringeren Durchsatz, unangemessene Aufgaben und Überlastung. Tester sehen sich ihrer Existenzgrundlage beraubt. Das Management sieht gesteigerte Kosten vor allem in der Einführungsphase. Diese Umbrüche müssen aktiv begleitet werden, sodass auf allen Ebenen Verständnis, Akzeptanz und im besten Fall Begeisterung für automatisierte Testung entsteht. Die Methode Behaviour Driven Development fördert eine positive Einstellung der Mitarbeiter zum Thema, indem sie Testautomatisierung zum Teamsport macht. Wenn es gelingt die manuellen Wiederholtestaufwänden (sogenannte Regressiontests) kontinuierlich durch Testautomatisierung zu senken, wird das positive Image bei allen Beteiligten verfestigt.

c. Architektur

Die weiter unten beschriebenen Techniken zur Durchführung von Tests können nur dann umgesetzt werden, wenn schon beim Entwurf des Gesamtsystems die Wartbarkeit, Erweiterbarkeit und Testbarkeit berücksichtigt wurde. Bei einem System, dessen Komponenten stark miteinander gekoppelt sind und die über wild gewachsene Schnittstellen miteinander kommunizieren, ist es nahezu unmöglich, modulare Tests in isolierten Umgebungen durchzuführen. Jeder Test wird zwangsläufig zu einem Systemtest und ist entsprechend schwer zu warten und zeitaufwändig in der Durchführung. Klar abgegrenzte Komponenten und strikt definierte Schnittstellen sind Voraussetzung für eine effiziente Erstellung und Ausführung von Tests.

3. Testmethode

Bei einem Test wird das zu testende Objekt analysiert. Diese Analyse kann anhand von zwei Methoden erfolgen: bei statischen Tests wird die Struktur des Objekts betrachtet, bei dynamischen Tests das Verhalten.

a. Statische Analyse

Bei der statischen Analyse wird das Testobjekt dahingehend überprüft, ob es zuvor definierte Qualitätskriterien erfüllt. Bei ausführbaren Modulen (Java, Typescript, SQL etc.) wird im Rahmen der statischen Code-Analyse der Quellcode eingelesen und dahingehend überprüft ob z.b. Stilvorgaben erfüllt sind, Namenskonventionen eingehalten wurden, aber auch ob Sicherheits-Schwachstellen oder Antipattern implementiert wurden. Bei deklarativen Artefakten (Konfigurationsdateien, Oberflächenbeschreibungen, Workflowdefinitionen etc.) werden die Definitionsdateien eingelesen, analysiert und ebenfalls auf Stil, Konventionen, ungültige Referenzen und Antipattern überprüft. Die statische Analyse kann weitestgehend automatisiert mit Tool-Support erfolgen, dabei hat sich neben dem Linten in der IDE (Integrated Development Environment, integrierte Entwicklungsumgebung) des Projekts, die Plattform SonarQube als Branchenstandard etabliert, darin werden sogenannte Quality Gates je nach Programmiersprache konfiguriert und deren Einhaltung im Projekt kontrolliert.

b. Dynamische Analyse

Bei der dynamischen Analyse wird das Testobjekt in einer zuvor konfigurierten Testumgebung ausgeführt. Je nach Ebene, auf der die Testung erfolgt, ist die Bereitstellung einer Testumgebung mehr oder weniger aufwendig. Ausführbare Module werden z.B. in einer reduzierten Laufzeitumgebung ausgeführt. Externe System werden durch sogenannte Mock-Objekte simuliert. Wenn das zu testende Modul bereit ist, werden die einzelnen Funktionen mit Testdaten aufgerufen und das Ergebnis der Funktion mit einem zuvor definierten erwarteten Ergebnis verglichen. Der Test ist genau dann erfolgreich, wenn geliefertes und erwartetes Ergebnis identisch ist.

4. Ausführungsart

Tests können durch einen menschlichen Tester manuell oder automatisiert ausgeführt werden.

a. Automatische Ausführung

Bei der automatischen Ausführung werden die zuvor definierten Tests im Rahmen des Build-Vorgangs ausgeführt. Zusätzlich können bestimmte Tests, unabhängig vom Build, per Zeitsteuerung regelmäßig das Gesamtsystem testen. Üblicherweise wird der Build-Vorgang durch eine Veränderung des Quellcodes im versionierten Repository (z.b. Git oder SVN) ausgelöst. Vorteile der automatischen Ausführung sind Geschwindigkeit, Vollständigkeit und Objektivität. Auch das Wissen über die Test-Abläufe ist in den Test-Definitionen enthalten und kann nicht (z.B. durch Abwanderung) verloren gehen. Zusätzlich lassen sich über die ausgeführten Tests Metriken anwenden und Reports erzeugen, die einen Rückschluss auf die Qualität des Systems erlauben. Voraussetzung für automatisierte Tests ist die kontinuierliche Integration der Software durch einen CI Server (z.b. GitLab CI oder Jenkins).

b. Manuelle Ausführung

Bei der manuellen Ausführung führt eine Person die Tests manuell durch. Hierbei wird zwischen geplanter und explorativer Testung unterschieden. Bei der geplanten Testung werden Testpläne mit Testfällen und Testschritten erstellt, die dann von gering qualifizierten Testern Schritt für Schritt durchgeführt werden. Diese Aufgabe ist ermüdend und zeitaufwendig und führt nicht selten aus mangelnder Konzentration zu unzuverlässigen Testergebnissen.

Bei der explorativen Testung prüft ein qualifizierter Tester das System ohne weitere Vorgaben. Hier hängt es stark von der einzelnen Person ab, ob der Test verwertbare Ergebnisse liefert. Dieses Vorgehen ist jedoch gerade bei Akzeptanztests ein wesentlicher Baustein, da so auch ungewöhnliche Pfade durch eine Anwendung geprüft werden können.

5. Test Ebenen

Fehler haben verschiedene Ursachen und wirken sich unter Umständen erst an räumlich und zeitlich weit entfernten Punkten aus. Je feiner das Netz der Tests um die einzelnen funktionalen Komponenten gelegt wird, umso leichter ist es, den ursächlichen Fehler zu lokalisieren (root cause analysis). Erst wenn sichergestellt ist, dass elementare Funktionen korrekt implementiert sind, ist es sinnvoll, diese in einen größeren Kontext einzubinden. Dementsprechend sollte auch die Testabdeckung der Ebenen gewichtet werden, so dass eine Testpyramide entsteht.

Softwaretest-Pyramide

Abbildung 1: die Softwaretest-Pyramide

a.  Unit/Modul Tests

Die Basis für jede Testung bilden Unit-Tests (auch Modul-Tests genannt). Ein oder mehrere Unit-Tests überprüfen eine einzelne Fachfunktion. Beispiele sind eine Java Funktion zur Preisumrechnung mit der gesenkten Mehrwertsteuer, oder eine Typescript Funktion zur Validierung von Eingaben in einem Webformular. Unit-Tests werden in der gleichen Programmiersprache geschrieben wie die funktionale Einheit, die sie testen (z.b. mit JUnit für Java). Hierdurch bleibt der Aufwand für die Entwickler des Moduls, die auch für die Tests verantwortlich sind, gering. Diese Tests liefern unmittelbar Ergebnisse, weil sie mit lokalen Daten arbeiten.

b.  Komponententests

Die Komponenten Tests überprüfen das korrekte Zusammenspiel verschiedener Module die gemeinsam eine fachliche Funktion liefern. Z.B. Modul Nettopreisberechnung mit Mehrwertsteuersatz-Abfrage. Auch diese Tests werden in der gleichen Programmiersprache vom Entwickler selbst geschrieben und nutzen lokale Daten, die über Mock-Services generiert werden (z.b. Mockito für Java). Sie sind bereits komplexer in der Komposition, laufen aber unabhängig von Umsystemen und liefern Ergebnisse schnell.

c.  Integrationstests

Bei einem Integrationstest wird das Zusammenspiel einzelner Komponenten miteinander geprüft. Im Fokus stehen hier die Schnittstellen zwischen den Komponenten. Die Komplexität ist deutlich höher als bei Modul Tests, auch hier können jedoch einzelne externe Systeme durch Mock-Services simuliert werden. Voraussetzung für den Einsatz von Mock-Services ist eine Architektur, die diese Art der Testung bereits vorsieht. Durch die Abhängigkeit von Umsystemen werden Testergebnisse unterschiedlich schnell erzeugt.

d.  Systemtest

Bei einem Systemtest wird schließlich das gesamte System in einer isolierten Umgebung getestet. Diese Umgebung entspricht so weit wie mögliche der produktiven Umgebung. Hier werden keine externen Systeme mehr durch Mock-Objekte oder Mock-Services simuliert. Neben den automatisierten Tests, die dann auch Deployment-Szenarien prüfen, werden hier auch Akzeptanz- und Performance-Tests durchgeführt. Auf dieser Ebene kann nun auch die Benutzeroberfläche (UI) automatisiert geprüft werden, indem ein programmierter Testroboter die Eingaben der Benutzer simuliert.

6. Test Ziele

Durch jeden Test soll genau eine Eigenschaft des Testobjekts überprüft werden. In der agilen Softwareentwicklung legen Definition of Done und Akzeptanzkriterien den Zielkorridor fest, für die Prüfung der erforderlichen Eigenschaften.

Zielquadrant für die Testung: „Das Richtige, richtig entwickelt.“

Abbildung 2: Zielquadrant für die Testung: „Das Richtige, richtig entwickelt.“

Die prüfbaren Eigenschaften werden im Folgenden beschrieben:

a. Korrektheit

Die Korrektheit einer Funktion zu prüfen ist das naheliegende Ziel einer Testung. Die Prüfung der Eigenschaft Korrektheit erfolgt, indem das Ergebnis einer Funktion mit einem zuvor definierten erwarteten Ergebnis verglichen wird. Die Funktion wird als korrekt betrachtet, wenn das Ergebnis in den zuvor definierten Toleranzgrenzen (z.B. bei Rundungsfehlern) liegt. Durch einen Test kann man nur das Vorhandensein von Fehlern zeigen, nicht jedoch deren Abwesenheit. Die Herausforderung bei dieser Art von Tests ist es, mit möglichst wenigen Testfällen eine hohe Abdeckung des Definitionsbereichs der Funktion abzudecken.

b. Datenqualität

Datenqualität ist ein Sammelbegriff für verschiedene Qualitätskriterien, die auf Daten angewendet werden. Hierzu zählen unter anderem Korrektheit, Form und Vollständigkeit. Form und Vollständigkeit werden über statische Analyse nach zuvor definierten Regeln geprüft. Die Prüfung der Korrektheit benötigt in der Regel tiefes Fachwissen, welches dann in individuelle Test-Methoden überführt wird.

c.  Performanz

Mit Performanz-Tests wird das Laufzeitverhalten der Funktion/des Systems geprüft. Hierzu werden üblicherweise große Datenmengen in das System gegeben oder mit einer hohen Anzahl von simulierten Nutzern gleichzeitig auf das System zugegriffen. Geprüft wird, ob sich die Reaktionszeit und der Ressourcenverbrauch (Rechenzeit, Arbeitsspeicher, Plattenspeicher) innerhalb der zuvor definierten Grenzen bewegt. Performanz-Tests sind sehr zeitaufwendig und erfolgen deshalb außerhalb des ständigen Build-Prozesses.

d. Fehlertoleranz/Resilienz

Je nach Kritikalität des Systems ist dessen Verfügbarkeit von entscheidender Bedeutung für der Erfolg des Unternehmens. Eine auf Fehlertoleranz ausgelegte Architektur kann viele der in komplexen Systemen auftretenden technischen Probleme abfangen. Die Implementierung dieser Architektur wird geprüft, indem der Ausfall einzelner Komponenten simuliert bzw. herbeigeführt wird. Ein System gilt dann als fehlertolerant, wenn es trotz solcher Störungen (ggf. unter akzeptierten Einschränkungen) funktional bleibt.

e. Sicherheit

Der Schutz vor unbefugtem Zugriff ist eine zentrale Anforderung an jedes System, welches mit vertraulichen Daten arbeitet. Die Umsetzung der am Markt gängigen Verfahren zum Schutz des Systems ist nicht trivial und damit fehleranfällig. Im Rahmen von Sicherheitstests werden die Verfahren getestet, die zur Authentifikation, Autorisation und Gewährleistung der Vertraulichkeit und Authentizität der verwalteten Daten genutzt werden.

f. Akzeptanz

Bei Akzeptanztests wird formal geprüft, ob das System den zuvor vereinbarten Anforderungen genügt. Ein System wird dann akzeptiert, wenn die zur Verfügung gestellten Funktionen die Bedürfnisse der Nutzer erfüllen und die zugrundeliegenden Geschäftsprozesse korrekt und vollständig abgebildet werden. Akzeptanztests werden häufig in Form von Szenarien durch Domänen Experten (Subject Matter Experts) in einer einfachen Metasprache erstellt, auch genannt Behaviour Driven Development (BDD). Die Szenarien können dann von geeigneten Test-Frameworks (z.B. mit Cucumber) auch automatisiert durchgetestet werden. Zusätzlich können mit UI-Testframeworks (z.b. Selenium Webdriver) Testroboter programmiert werden, die Eingaben auf der Mensch-Computer-Schnittstelle simulieren und erwartetes Verhalten prüfen. Diese automatisierten Akzeptanztest eignen sich besonders für den Wiederholtestumfang (Regressiontests) von kritischen Geschäftsvorfällen, weil kein hoher Pflegeaufwand anfällt und hohe Risiken abdeckt werden. Sie laufen meist regelmäßig per Zeitsteuerung auf Gesamt-Systemebene, erzeugen Reports und gegebenenfalls Fehlertickets.

g. Benutzbarkeit/Usability

Die Benutzbarkeit und Verständlichkeit des Systems werden in der Regel an Prototypen getestet. Üblich sind hier das Review der Oberfläche durch UX-Experten und Praxistests durch eine repräsentative Menge von Anwendern. Diese Anwender bearbeiten unter Beobachtung zuvor definierte Aufgaben. Die Auswertung der Beobachtungen führt dann zu Korrekturvorschlägen oder der Akzeptanz des Systems.

7. Test Auswertung

Das Ausführen von manuellen und automatischen Tests stellt in erster Linie sicher, dass keine fehlerhaften Module, Komponenten oder Systeme in die Produktionsumgebung gelangen und dort Probleme bereiten. Daneben stellen die Testergebnisse eine wertvolle Basis für die Beurteilung der Produktqualität dar und schaffen Vertrauen in die Zuverlässigkeit der Softwareentwicklung. Da die Tests alle Aspekte des Systems betrachten, lassen sich über entsprechende Metriken Aussagen über die verschiedenen Eigenschaften das Systems und der verarbeiteten Daten treffen. Die regelmäßige Ausführung der Tests ermöglicht eine Trendanalyse, die Ausgangspunkt für korrigierende Maßnahmen ist. Mithilfe von Testautomatisierungs-Frameworks lassen sich die entsprechenden Reports und Fehlertickets maschinell erzeugen und wertvolle Zeit im Projektteam sparen.

a. Testumgebungen

Bei der Ausführung von Tests müssen verschiedene Aspekte gegeneinander abgewogen werden. Idealerweise wird jeder Test in einer exakten Kopie der Produktionsumgebung durchgeführt, um realistische Ergebnisse zu erzielen. Es ist offensichtlich, dass diese Anforderung nicht zu erfüllen ist. Der Betrieb eines Klons der Produktionsumgebung ist mit hohem Aufwand verbunden und in der Regel nicht einfach und schnell in einen Grundzustand zurückzuversetzen. Während der Entwicklungsphase ist jedoch ein frühes und schnelles Feedback durch Testergebnisse erforderlich.

Es hat sich daher bewährt Tests in unterschiedlichen Umgebungen durchzuführen, die jeweils unterschiedliche Anforderungen adressieren.

Umgebung Eigenschaften/ Zweck
Development – Geringe Datenmengen, generiert
– Schnelle Initialisierung und Freigabe
– Tests während der Entwicklung, Live Tests
– Eigene Umgebung je Entwickler
Test – Repräsentativer Auszug echter Daten, jedoch anonymisiert
– Integrationstests
– Vorab-Performance-Tests
– Vorab-Reviews
– Eine Umgebung für alle Entwickler
– Entwicklungsorientiert
Acceptance – Vollständige Kopie der echten Daten, wenn möglich nicht anonymisiert
– Performance-Tests
– Akzeptanz-Tests
– QS orientiert
Production – Produktionsumgebung (Live)

Jetzt teilen auf:

Kommentar

  1. kohleverstromung industrie 21. April 2021 at 6:04 - Reply

    Danke fuer die Info

Jetzt kommentieren