Testen von Cloud Services 

 1. September 2012

Moderne IT-Systeme werden immer größer und komplexer. Sie einmalig zu bauen ist vielleicht mit professioneller Hilfe möglich, aber mit der Erhaltung und Weiterentwicklung derart komplexer Systeme sind die Anwender oftmals überfordert. Durch die ständige Entwicklung neuer Systeme potenziert sich das Wartungsproblem. Software muss ständig korrigiert, geändert, saniert und fortentwickelt werden, um mit der betrieblichen Realität Schritt zu halten. Je mehr neue Software entsteht, desto mehr Kapazität wird benötigt um sie zu erhalten. Anwender brauchen deshalb immer mehr Personal um einerseits die alten Systeme zu erhalten und anderseits neue Applikationen zu bauen.

Es ist keine Lösung immer mehr Code, immer schneller herzustellen. Das Ziel muss stattdessen sein, die Funktionalität zu gewinnen ohne den eigenen Code zu vermehren. Es gilt die Codemasse einzuschränken und trotzdem die erforderliche Funktionalität bereitzustellen. Zu erreichen ist dies nur durch die Nutzung fremder, vorgefertigter Bausteine, die der Anwender nicht selbst entwickeln und erhalten muss. Die Verantwortung für die Pflege und Weiterentwicklung liegt beim Anbieter. Das Aufkommen von Cloud Computing verspricht eine Lösung zu diesem Problem. In der Wolke hat der Anwender die Möglichkeit, die Vorteile vorgefertigter Software mit den Vorteilen der eigenen Entwicklung zu kombinieren. Es muss nicht jedes Detailproblem vom Anwender selbst gelöst werden. Er benutzt die Standardlösungen und konzentriert seine Kraft auf die wirklichen betriebsspezifischen Funktionen.

Service-orientierte Anforderungsanalyse

Voraussetzung für die Nutzung von Cloud-Services ist die Service-orientierte Anforderungsanalyse. Am Anfang steht die Modellierung des Geschäftsprozesses, um den Kontext der Applikation abzustecken. Dann beginnt eine Suche nach Services, die für die Lösung des Problems in Frage kommen.

Man sucht nach Bausteinen, die für das geplante System verwendet werden können. Erst wenn die Liste potentieller Bausteine ausreichend ist, beginnt der Anwender seine Anforderungen zu detaillieren und zwar so, dass sie zu den verfügbaren Services passen. Die funktionalen und nicht-funktionalen Anforderungen legen die Minimumabnahmekriterien fest. Hier werden nur Funktionen beschrieben, die unbedingt vorhanden sein müssen, und Qualitätsgrenzen festgelegt, die unbedingt eingehalten werden müssen.

Die Anforderungsspezifikation enthält folgende Inhalte:

  • Funktionale und nicht-funktionale Anforderungen
  • Geschäftsobjekte als Anhaltspunkt für die Daten, die dem Service zur Verfügung gestellt werden müssen
  • Geschäftsregeln als gewünschte Verarbeitungslogik der
    ausgewählten Services
  • Systemakteure als die Subjekte der Anwendungsfälle
  • Prozessauslöser, die Anwendungsfälle anstoßen
  • Anwendungsfälle
  • Geschäftsschnittstellen

Dieses Dokument muss als solches automatisch analysierbar sein, denn es gilt, einerseits die Verarbeitungsschritte der Anwendungsfälle mit den Operationen der potentiellen Services abzugleichen und anderseits Testfälle für den Test der Services zu generieren. Der Hauptzweck der Anforderungsdokumentation ist als Testorakel zu dienen. Sie muss deshalb mit der Schnittstellendefinition vergleichbar und somit auf der gleichen semantischen Ebene sein. Gleichermaßen enthält es Informationen, die es nach oben mit dem Geschäftsprozess verbindet. Insofern ist das Dokument ein Bindeglied zwischen dem übergeordneten Geschäftsprozess und den untergeordneten Services.

Das Service-Testverfahren

Das Testverfahren sieht zwei Phasen vor:

  • Statische Analyse
  • Dynamische Analyse

Statische Analyse

Die statische Analyse vergleicht den Inhalt der Anforderungen mit dem Inhalt der Schnittstellendefinition. Ein Textanalysator scannt die Spezifikation und baut Tabellen der Anwendungsfälle, Verarbeitungsschritte und Schnittstellendaten auf. Außerdem wird eine Tabelle der Testfälle aufgebaut. Für jeden Verarbeitungsschritt, jede Aktion, jeden Zustand und jede Regel wird ein passender Testfall erzeugt. Die Testfälle werden mit Information aus den Schnittstellendefinitionen ergänzt. Parallel dazu wird das Interface Schema analysiert. Neben der Prüfung der Regeln und die Vermessung der Größe, Komplexität und Qualität der Schnittstellen, werden auchhier Tabellen aufgebaut. Danach werden die Tabellen aus der Spezifikationsanalyse mit denen aus der Schnittstellenanalyse verglichen. Die Verarbeitungsschritte der Anwendungsfälle werden mit den Operationen, die Geschäftsschnittstellendaten mit den Parameterdaten der Operationen gepaart. Wo eine Paarung nicht zusammenkommt, wird auf eine Inkompatibilität verwiesen.

Statische Analyse
Statische Analyse

Falls sich ein Service inkompatibel mit den Vorstellungen des Benutzers erweist, hat der Anwender vier Alternativen:

  • Das Service ablehnen und weiter suchen
  • Seine Anforderungen dem Service anpassen
  • Einen Wrapper um das Service bauen, um die Ergebnisse des Services seiner Anforderungen anzupassen
  • Ein eigenes Service entwickeln

Der Anwender wird von Fall zu Fall entscheiden, welche dieser Alternative am besten passt. Was wir vermeiden wollen ist, dass der Anwender beginnt, eigene Services zu entwickeln. Diese Alternative soll nur als letzte Möglichkeit zugelassen werden.

Am Ende der statischen Analyse wissen wir zum einen, ob das Service aufgrund seiner Schnittstellendefinition überhaupt in Frage kommt. Dafür haben wir ihre Größe, Komplexität und statische Qualität vermessen. Zum anderen können wir Struktur und Inhalt der Service-Schnittstellendefinition mit der Struktur und dem Inhalt, die wir gerne hätten, vergleichen. Wenn sie zu weit auseinander liegen, brauchen wir mit der zweiten Phase – der dynamischen Analyse – gar nicht anzufangen.

Dynamische Analyse

Bei der dynamischen Analyse wird das Service ausgeführt und die Ergebnisse zu Vergleichszwecken festgehalten. Ausgangspunkt für die dynamische Analyse ist das Schema der Schnittstelle und die Testfalltabelle, die aus der Anforderungsspezifikation gewonnen wurde.

Die Analyse beinhaltet acht Schritte:

  1. Der Tester ergänzt die Testfalltabellen mit Wertzuweisungen
  2. Aus der Testfalltabelle und dem Schnittstellenschema wird ein Testskript generiert
  3. Der Tester ergänzt die Testskripte mit weiteren Vor- und Nachbedingungen
  4. Die Testskripte werden compiliert und Testobjekte gebildet
  5. Aus dem Schnittstellenschema und den Vorbedingungen der Testobjekte werden Requests generiert
  6. Die Requests werden der Reihe nach abgeschickt und die entsprechenden Responses abgefangen
  7. Die Responses werden gegen die Nachbedingungen der Testobjekte validiert
  8. Die Testmetrik wird evaluiert

Die Testfalltabelle, die aus der Anforderungsspezifikation generiert wird, ist nicht vollständig. Z.B. muss die Zuweisung der Testwerte vom Tester noch ausgefüllt werden. Ein Automat vereinigt dann die Testfalltabelle mit der Schnittstellendefinition zu einem strukturierten Testskript. Der Tester kann das Skript verfeinern und ergänzen.

Von hier an läuft alles automatisch ab. Aus den Skripten gehen Testobjekte hervor. Der Generator verbindet das Schnittstellenschema mit den Vorbedingungen, um für jeden Testfall eine Reihe Requests zu generieren. Anschließend werden die Requests von einem Testtreiber abgeschickt. Dieser empfängt auch die Responses und speichert sie. Der Validator vergleicht Response mit den Nachbedingungen und weist abweichende Werte in einem Mängelbericht aus.

Im letzten Schritt wird die Testmetrik aggregiert und evaluiert (Testüberdeckung, Korrektheit, Performance-Rating, etc.).
Mit Hilfe des Testmetrik-Berichts kann der Tester beurteilen in wie weit das Verhalten des Service für die Zielapplikation geeignet ist.

Die Ergebnisse des Tests dienen als Entscheidungshilfe und dafür müssen sie in einer Form präsentiert werden, die der Entscheider leicht versteht und beurteilen kann.

Zusammenfassung

Code-Bausteine werden in Zukunft vermehrt als fertige Services angeboten, die der Anwender nur in seine Geschäftsprozesse einzubauen braucht. Programmiert wird, wenn man überhaupt diese Bezeichnung verwenden darf, in einer höheren Prozessbeschreibungssprache wie BPMN, S-BPM und BPEL. Von dort aus werden die Schnittstellen bedient und die einzelnen Services aufgerufen. Die Anwender brauchen sich nicht mehr um die Detailimplementierung zu kümmern. Dennoch müssen sie die Bausteine, die sie verwenden, weiterhin testen. Einzeln in einem Service-Unittest, der hier beschrieben wurde, und im Ganzen in einem Integrationstest. Jedenfalls steht jetzt ein Paradigmenwechsel an. Wir steigen jetzt von der objekt-orientierten auf die service-orientierte Softwareentwicklung um. Damit soll das Erhaltungsproblem, das zu Beginn des Beitrages angesprochen wurde, wenn nicht endgültig gelöst, dann zumindest um einiges gelindert werden.

Literatur

  • Ardagna et. Al.: A Service-based Framework for flexible Business Processes, IEEE Software Magazine, 03 2011, p61
  • Bozkurt, Harman, Hassoun: Testing Web Services – A Survey. Journal on Software Testing, Verification & Reliability, Vol. 17, No. 2, Wiley and Sons, 2008
  • Carr: The big Switch, Harpers Books, New York, 2007
  • Grundy, Kaefer, Keong, Liu: Software Engineering for the Cloud, IEEE Software Magazine, 03 2012, p26
  • Riungu-Kalliosaari, Taipale, Smolander: Testing in the Cloud – Exploring the Practice, IEEE Software Magazine, 03 2012, p46
  • Shull: A brave new World of Testing – an Interview with Google’s James Whittaker, IEEE Software Magazine, 03 2012, p4
  • Sneed, Huang: The Design and Use of WSDLTest – a Tool for testing web services” (2007), Journal of Software Maintenance and Evolution, Vol. 19, No. 5, p297
  • Yau, Ho: Software Engineering meets Services and cloud Computing, IEEE Computer Magazine, 10 2011, p47