Testautomatisierung verteilter Systeme: Herausforderungen und Lösungsansätze
Die Testautomatisierung verteilter Systeme birgt einige Herausforderungen, da die Schnittstellen verteilt und häufig schwierig automatisch testbar sind. Dadurch wird die Automatisierung oft zu einem aufwändigen Prozess und manuelle Tests werden bevorzugt. Besonders die agilen Entwicklungsprozesse fordern jedoch automatisierte Tests, um den Anforderungen schneller Release-Zyklen gerecht werden zu können.
1 Herausforderungen
Im Folgenden möchte ich einige typische Herausforderungen hervorheben, die oft auftreten können. Diese Aufzählung basiert auf meinen persönlichen Erfahrungen und erhebt keinen Anspruch auf Vollständigkeit.
1.1 Benutzerschnittstellen schwierig automatisierbar
Häufig handelt es sich bei den Benutzerschnittstellen um akustische und visuelle Ausgabegeräte sowie nicht fernsteuerbare Bedienelemente, wie Schalter, Taster, Tastaturen usw. Um diese Schnittstellen «End-to-End» testen zu können, wären akustische und visuelle Auswertungssysteme sowie Eingaberoboter erforderlich. Wenn jedoch bereits beim Design die Testbarkeit berücksichtigt wird, können erhebliche Aufwände eingespart werden (siehe Kapitel 2.2).
Wenn ein System über automatisierbare Schnittstellen verfügt, wie z.B. Protokolle auf Ethernet-Basis (MQTT, HTML, REST, SSH usw.), können Tests relativ einfach mit diesen Schnittstellen durchgeführt werden. Dabei werden die tatsächlichen Geräte nicht einbezogen. Obwohl solche Tests nicht mehr als „End-to-End“-Tests gelten, kommen sie diesen dennoch nahe und decken einen grossen Teil des zu testenden Systems ab, und das mit deutlich weniger Aufwand. Darüber hinaus lassen sich solche Tests viel einfacher automatisieren.
1.2 Verteilte Benutzerschnittstellen
Für die Überprüfung der Systemanforderungen sind mehrere Ein- und Ausgabegeräte erforderlich. Dies deutet darauf hin, dass auch mehrere Eingaberoboter und Auswertungssysteme der Ausgaben für eine Testautomatisierung notwendig sind. In meiner Vergangenheit haben Überlegungen in diese Richtung stets gezeigt, dass die Wirtschaftlichkeit nicht gegeben ist, weil der Aufwand für die Testautomatisierung stets viel grösser war, als der Aufwand für das manuelle Testen. Es gilt also, einen guten Mix zwischen automatischen und manuellen Tests zu finden.
1.3 Begrenzte Ressourcen
In der Regel sind die Stückzahlen von komplexen Systemen gering, während die Kosten für die Entwicklung der Tests hoch sind. Im Allgemeinen ist es schwierig, eine umfassende automatisierte Testumgebung für solche Systeme auf höchster Ebene zu realisieren. Daher müssen viele Systemtests manuell durchgeführt werden, was im Widerspruch zum Trend agiler Entwicklung mit ihren kurzen Release-Zyklen steht. Was also sollen wir tun?
2 Lösungsansätze
Im Folgenden möchte ich, basierend auf meinen Erfahrungen, einige mögliche Lösungsansätze vorstellen.
2.1 Aufsetzen eines Testprojekts
Jedes Projekt zeichnet sich durch seine Einzigartigkeit aus. Diese Tatsache verdeutlicht, dass sich Testprojekte in ihren Eigenschaften unterscheiden und alle Aspekte stets hinsichtlich Durchführbarkeit, Effizienz und Verhältnismässigkeit geprüft werden müssen. Grundsätzlich gelten für Testprojekte die gleichen Prinzipien wie für andere Projekte.
Die Bedeutung des Testengineerings von Anfang an im Projektverlauf ist enorm! Unabhängig davon, was und wie getestet werden soll, erfordert es eine Analyse, Planung, Umsetzung, Betrieb und Wartung. Das Testen ist ein eigenständiges Teilprojekt innerhalb des Gesamtprojekts und erfordert entsprechende Ressourcen während der gesamten Entwicklungsphase. Wenn eine seriöse Qualitätssicherung gefordert ist, muss anerkannt werden, dass hierfür erhebliche Ressourcen zur Verfügung gestellt werden müssen. Testen kann nicht einfach nebenbei erledigt und auch nicht einfach ans Ende eines Projekts angehängt werden!
2.2 Testaspekte bereits bei der Systemarchitektur
Es bietet klare Vorteile, bereits bei der Systemarchitektur, der Entwicklung oder der Beschaffung einzelner Hardwarekomponenten an das Testen / Qualitätssicherung zu denken. Durch die Berücksichtigung dieser Aspekte im Systemdesign können erhebliche Kosten eingespart werden, da dadurch frühzeitig gute Voraussetzungen für das Testen geschaffen werden können. In der Regel ist es aufwändiger, Schnittstellen oder Funktionen nachträglich zu erweitern, als diese von Anfang an einzubauen.
2.3 Testumgebung
Der Herausforderung «Verteilte Benutzerschnittstellen auf verschiedenen Geräten», wie in Kapitel 1.2 beschrieben, sollte ebenfalls Beachtung geschenkt werden. Aus verschiedenen Gründen ist es oft nicht möglich, ein vollständiges Testsystem aufzubauen, und daher wird eine dedizierte Testanlage benötigt. Abhängig von der Komplexität kann die Beschaffung einer Testanlage ebenfalls als eigenständiges Teilprojekt betrachtet werden. Es gibt viele Aspekte zu planen, zu beschaffen, zu konstruieren, zusammenzubauen und schliesslich zu testen und warten.
2.4 Risiko basiertes Testen
Aus meiner Sicht sollte, wann immer möglich, ein risikobasierter Ansatz für das Testen gewählt werden. Dies bedeutet, sich auf das Wesentliche zu konzentrieren. Bei diesem Vorgehen werden die Auswahl, Priorisierung und Anwendung von Testaktivitäten und Ressourcen anhand der relevanten Risikotypen und Risikostufen ausgerichtet.
2.5 Berücksichtigen aller Teststufen
Es existieren verschiedene Teststufen mit unterschiedlichen Zielen, Vor- und Nachteilen. Je früher Fehler entdeckt werden, desto schneller und kostengünstiger können sie behoben werden. Daher ist es sinnvoll, bereits ab Beginn der Entwicklung automatisierte Tests (Unittests) einzuführen und zu pflegen. Allerdings reichen Unittests bei verteilten Systemen bei Weitem nicht aus. Es bedarf zusätzlicher Tests (Modul-, Integrations-, Teilsystem- und Systemtests), um jeweils einen immer grösseren Teil des gesamten Systems abzudecken. Mit der wachsenden Grösse des zu testenden Systems wird die Testautomatisierung in der Regel aufwändiger.
Eine sorgfältig durchdachte Teststrategie, die vom Unittest bis zum Systemtest reicht, ist von grosser Bedeutung, um effizientes und automatisiertes Testen zu ermöglichen. Doppelte Arbeit ist teuer und bringt keinen Mehrwert! Was automatisch getestet wird, braucht nicht zusätzlich noch manuell getestet werden.
Bei einem guten Verhältnis zwischen Auftraggeber und -nehmer können Test ggf. auch zum Auftraggeber ausgelagert werden, weil diesem z. B. die geeignete Infrastruktur zur Verfügung steht, damit nicht doppelt getestet werden muss.
2.6 Werkzeugbereitstellung
Eine solide „Werkzeugkiste“ trägt dazu bei, monotone und wiederkehrende Arbeiten zu minimieren. Eine geeignete, einfache und stabile Werkzeugkette ermöglicht zielgerichtetes und effizientes Entwickeln und Testen. Es sollte jedoch nicht vernachlässigt werden, dass die Auswahl, Einrichtung, Verwaltung und Wartung dieser Werkzeugkette während des gesamten Projekts und in der Wartung Ressourcen erfordert. Heutzutage werden diese Werkzeuge in die Entwicklungsumgebung integriert und DevOps-Spezialisten sorgen für einen reibungslosen Betrieb.
2.7 Lifecyle Management Werkzeug
Durch den Einsatz eines Lifecycle Management Werkzeugs kann die Effizienz, Transparenz und Qualität des Softwareentwicklungsprozesses signifikant verbessert werden. Es ermöglicht die Erfassung von Kennzahlen (KPIs = Key Performance Indicators), mit denen Entwicklungsprozesse effektiver überwacht werden können. Dadurch lassen sich Engpässe und Probleme identifizieren und die Zielerreichung verbessern. Diese Werkzeuge unterstützen eine kontinuierliche Verbesserung und ermöglichen eine datenbasierte Entscheidungsfindung. Darüber hinaus liefern sie wichtige Kennzahlen für die Planung zukünftiger Projekte.
3 Fazit
«Testen als eigenständiges Projekt»
Qualität kann nicht erst am Ende eines Produktentwicklungsprozesses getestet werden! Daher ist automatisiertes Testen auch keine Aktivität, die einfach am Ende eines Entwicklungsprojekts angehängt werden kann. Testautomatisierung unterliegt einem eigenen Lebenszyklus, ähnlich wie das Entwicklungsprojekt selbst. Das bedeutet, dass während des Entwicklungsprojekts kontinuierlich Ressourcen für das Testen benötigt werden. Die Testinfrastruktur muss aufgebaut, fortlaufend weiterentwickelt, gewartet und gepflegt werden, solange sie benötigt wird. Aus diesem Grund ist es sinnvoll, das Testen als eigenständiges Projekt zu betrachten und entsprechend zu planen und durchzuführen.
«Risikobasiertes Testen ermöglicht das «Richtige» ressourcenoptimiert zu testen»
Dabei ist es wichtig, die Wirtschaftlichkeit im Blick zu behalten. Bei allen Teststufen sollte eine Risikobewertung durchgeführt werden, um festzulegen, was, wie oft und wie intensiv getestet werden muss, um ein akzeptables Risiko mit minimalem Aufwand einzugehen.
Die Ergebnisse sollten idealerweise frühzeitig im Projekt in einem Testplan oder Testkonzept festgehalten werden und kontinuierlich an neue Gegebenheiten angepasst werden. Dadurch lässt sich auch der Ressourcenbedarf für die Planung ableiten.
«Früher Einbezug des Testteams»
Das Testteam sollte idealerweise so früh wie möglich, am besten ab dem Start des Gesamtprojekts, einbezogen werden. Es ist wichtig, die Testbarkeit der Anforderungen zu überprüfen und Einfluss auf die Systemarchitektur, das Design und die Testumgebung zu nehmen.
Obwohl ich nicht speziell auf das Anforderungsmanagement eingegangen bin, ist es von grosser Bedeutung. Denn was sollen die Tester testen, wenn die Entwickler nicht wissen, was sie entwickeln sollen? Bereits beim Überprüfen der Anforderungen können Tests schrittweise abgeleitet werden, um sicherzustellen, dass alle erforderlichen Aspekte getestet werden.
«Kennzahlen ermöglichen dem Management faktengestützte Entscheidungen»
Das Erfassen von Kennzahlen spielt eine wichtige Rolle bei der Steuerung des Entwicklungsprozesses und liefert dem Management faktengestützte Informationen für die Entscheidungsfindung. Sie bieten eine solide Grundlage für die Aufwandschätzung zukünftiger Aufgaben und Projekte. Indem relevante Metriken erfasst und analysiert werden, können fundierte Entscheidungen getroffen werden, um den Entwicklungsprozess effektiver zu gestalten und die Ressourcen optimal einzusetzen.