p.blog
Unternehmenskultur, Softwareentwicklung und Architektur

1. Juni 2021

Testautomatisierung. Anleitung zum Glücklichsein

5 Minuten Lesedauer

Im Beitrag Test-Ziele – Warum wir automatisiert testen haben wir uns damit auseinandergesetzt, weshalb Testautomatisierung eine gute Idee ist. White-/Black-Box-Testing haben wir in Are you ready to think outside the box? und Testing in Boxes gleich aus zwei Perspektiven betrachtet. Wir müssen das jetzt nur endlich machen. Dabei stellen wir fest, dass Testautomatisierung gar nicht so einfach ist und wir im Zweifelsfall scheitern können.

Photo by amin khorsand on Unsplash

 

Wir brauchen einen Plan

Da ist sie: unsere historisch gewachsene Anwendungs- und Service-Landschaft. Mehr als eine Million Codezeilen sind darin verbaut. Leider gibt es noch keine automatisierten Tests. Warum das so ist, verliert sich in der Historie unserer Organisation.

Wichtig ist doch, dass wir jetzt damit starten. Apropos: Wie machen wir das?

Ich habe da einen Plan!

Funktionsübersicht erstellen

Zum Start brauchen wir eine Übersicht, welche Funktionen überhaupt in unserer Service-Landschaft verfügbar sind. Klingt banal, es ist bei so einer gewachsenen Landschaft aber alles andere als trivial, einen Überblick zu bekommen.

Das kostet doch nur Zeit! Sollten wir nicht einfach loslegen? Bevor du den Plan gemacht hast, habe ich doch schon sieben Tests automatisiert!

Warte mal! Wenn du mit Testautomatisierung für einen einzelnen Service mit überschaubarem Funktionsumfang starten willst, ergibt es Sinn einfach loszulaufen. Bei einem komplexeren System oder wie in unserem Fall einer ganzen Service-Landschaft solltest du deine Kapazität an den richtigen Stellen einsetzen. Dafür brauchst du einen Überblick.

Verwendungshäufigkeit messen

Wie häufig werden die einzelnen Funktionen eigentlich verwendet? Wie wichtig sind diese? Die schnelle Antwort – jede Funktion ist wichtig und wird häufig ausgeführt – ist meist falsch. Auch wenn die Studie der Standish Group aus dem Jahr 2002 alt ist, hat ihre Kernaussage nach unserer Erfahrung immer noch Gültigkeit: Danach wird nur ca. ein Drittel der Funktionalität eines Software-Systems mit einer nennenswerten Häufigkeit benutzt.

Standish Group Study 2002

He komm! Nur ein Drittel? Das glaube ich jetzt nicht.

Mmh, tja. Wenn das auch nur ansatzweise stimmt, tun wir gut daran herauszufinden, welche Funktionen signifikant häufig verwendet werden. Bei diesen fokussieren wir unsere Automatisierungskapazität.

Risikoklassen festlegen

Welche Risikoklasse hat meine Funktionalität? Es gibt definierte Risikoklassen für Software im Gesundheitsbereich, die sich aber in anderen Kontexten nicht anwenden lassen. Also stellen wir unsere eigenen Klassen auf. Was passiert also, wenn in einer unserer Funktionen ein Fehler auftritt? Die Auswirkungen sind:

  • vernachlässigbar

  • minimal

  • mittel

  • hoch

  • schwerwiegend

  • kritisch

  • katastrophal

Wahrscheinlichkeitsklassen festlegen

Wie wahrscheinlich ist das Auftreten eines Fehlers in meiner Funktionalität? In unserer gewachsenen Systemlandschaft durften wir bestimmt viele Erfahrungen sammeln, wo und wie häufig Fehler aufgetreten sind. Hier lässt sich eine einfache Liste erstellen:

  • häufig

  • mittel

  • manchmal

  • selten

  • gar nicht

Einordnung in Risikomatrix

Als nächstes ordnen wir unsere Funktionen in eine Risikomatrix ein, als deren Dimensionen die festgelegten Risiko- und Wahrscheinlichkeitsklassen benutzt werden. Der Buchstabencode steht für unsere relevanten Funktionen. Die Kunst bei dieser Bewertung ist, die Risikoklassen der Funktionen nicht systematisch zu hoch einzuschätzen.

Das kostet jetzt schon wieder eine Menge Aufwand! Muss das wirklich sein?

Wenn du die Funktionen grob genug geschnitten hast, ist das gar nicht so viel. In unserem Fall haben wir 20 Funktionen identifiziert, die häufig genug verwendet werden, um überhaupt in unserer Risiko-Matrix betrachtet zu werden.

Änderungshäufigkeit bewerten

Der nächste Schritt in unserer Anleitung zum Glücklichsein ist Bewertung der erwarteten Änderungshäufigkeit unserer relevanten Funktionen. Wir nutzen einen einfachen Farbcode.

  • rot – häufig
  • blau – mittel
  • gelb – selten
  • schwarz – gar nicht

Risikomatrix bewerten

Wir müssen davon ausgehen, dass wir – egal welches Bild die Risikomatrix ergibt – nicht genug Kapazität zur Verfügung haben, um alle für unsere Service-Landschaft sinnvollen Tests zu automatisieren. Also müssen wir priorisieren.

Auch hier nutzen wir einen einfachen Farbcode. Testautomatisierung für die Funktionalität mit rotem Hintergrund hat die höchste Priorität, blauer Hintergrund heißt mittlere Priorität, gelber Hintergrund hat die niedrigste Priorität.

Was bedeutet der graue Hintergrund?

Hier soll die Priorisierung besser einzeln – also pro Funktionalität – entschieden werden. Funktion O hätte z.B. hohe Priorität.

Mmh, ok. Aber warum haben manche blaue Funktionen mittlere Priorität und manche hohe Priorität?

Das hängt mit ihren jeweiligen Risiko- und Wahrscheinlichkeitsklassen zusammen. Es spricht aber nichts dagegen, allen blauen Funktionen hohe Priorität zuzuordnen. Der Farbcode für die Priorisierung soll lediglich helfen, knappe Kapazität bei der Testautomatisierung zu steuern.

Einordnung in Testpyramide

Mit der Testpyramide haben wir uns in Was alte Kulturen mit Softwaretests verbindet befasst. Hier gibt es noch mal die Kurzfassung.

Die Einordnung von Tests in die Testpyramide legt implizit die Teststrategie fest, die eine Organisation verfolgt. Die unterschiedliche Größe der drei Layer für Unit-, Service- und UI-Tests symbolisiert den Schwerpunkt der Tests im jeweiligen Systemkontext.

Unit-Tests – Tests auf Code-Ebene – bilden üblicherweise die Masse der Tests.

Service- oder Integrationstests prüfen modul-, komponenten- oder systemübergreifend und sind weniger zahlreich als die Unit-Tests.

UI-Tests nutzen die Benutzeroberfläche eines Systems für die Validierung – im Idealfall exakt so, wie dies ein Benutzer tun würde. Sie sind zahlenmäßig häufig klar in der Minderheit.

Wieso steht da zweimal API?

Wir unterscheiden in unseren Systemen an zwei Stellen APIs: zwischen Modulen, Komponenten, Services oder Systemen und zwischen Services und der Benutzeroberfläche (sogenannte Backend-for-Frontend-APIs)

Und Unit-Tests sind schnell preiswert während UI-Tests langsam teuer werden?

Äh, nicht ganz. Unit-Tests lassen sich in aller Regel mit überschaubarem Aufwand erstellen und haben eine hohe Ausführungsgeschwindigkeit. UI-Tests zu erstellen ist meist teurer; die Ausführung von UI-Tests dauert im Vergleich zu Unit-Tests deutlich länger, weil häufig Klickpfade auf der Oberfläche einer Anwendung durchlaufen werden müssen, um eine bestimmte Funktionalität zu prüfen.

Vorletzter Schritt in unserer Anleitung zum Glücklichsein ist es, den bewerteten Funktionen aus der Risikomatrix eine Heimat in der Testpyramide zu geben. Die Einordnung bedeutet keineswegs, dass eine Funktionalität ausschließlich mit Service-Tests abgedeckt werden sollte. Sie legt einen Schwerpunkt fest, der uns wiederum hilft unsere Automatisierungskapazität zu überwachen.

Automatisieren. Automatisieren. Automatisieren

Jetzt erstellen wir für unsere wichtigen und kritischen Funktionalitäten automatisierte Tests gemäß ihrer Priorität und ihrer Einordnung in die Testpyramide.

Und dann?

Dann ist unsere Testautomatisierung bald gut genug. Und wir sind glücklich.

Zusammenfassung

Das waren ziemlich viele Schritte. Wir fassen sie zur Sicherheit noch einmal zusammen:

  1. Funktionsübersicht erstellen
  2. Verwendungshäufigkeit messen
  3. Risikoklassen festlegen
  4. Wahrscheinlichkeitsklassen festlegen
  5. Funktionen in Risikomatrix einordnen
  6. Änderungshäufigkeit der Funktionen bewerten
  7. Risikomatrix bewerten
  8. Funktionen in Testpyramide einordnen
  9. Gemäß Priorisierung automatisieren

Wenn wir am Ende der Liste angekommen sind, hat sich unsere System- und Service-Landschaft sicher bereits weiterentwickelt. Aber inzwischen haben wir es hoffentlich gelernt, automatisierte Tests schon während der Entwicklung neuer oder Änderung bestehender Funktionalität zu erstellen oder anzupassen. Die Liste periodisch zu überfliegen wird uns aber sicher dabei helfen, die Testautomatisierung weiter zu verbessern.

Schließlich wollen wir ja glücklich bleiben.