Diplomarbeit. Fakultät für Mathematik, Informatik und Naturwissenschaften Research Group Software Construction

Größe: px
Ab Seite anzeigen:

Download "Diplomarbeit. Fakultät für Mathematik, Informatik und Naturwissenschaften Research Group Software Construction"

Transkript

1 Fakultät für Mathematik, Informatik und Naturwissenschaften Research Group Software Construction Diplomarbeit Ein Ansatz zum modellgetriebenen Testen von EJB-basierten Informationssystemen An Approach for Model Driven Testing of EJB Based Information Systems Steen Conrad März, 2012 Gutachter: Prof. Dr. rer. nat. Horst Lichter Prof. Dr. rer. nat. Bernhard Rumpe Betreuer: Dipl.-Inform. Matthias Vianden

2

3 Hiermit versichere ich, dass ich die vorliegende Arbeit selbständig verfasst und keine anderen als die angegebenen Quellen und Hilfsmittel benutzt sowie Zitate kenntlich gemacht habe. Aachen, den 07. März 2012 Steen Conrad

4

5 Inhaltsverzeichnis I Einleitung und Grundlagen 1 1 Einleitung Überblick über die Diplomarbeit Aufgabenstellung Ziele der Diplomarbeit Gliederung Grundlagen Model Driven Architecture Modellierungsebenen Begrie Nutzen der MDA Entwurfsmuster Testen Grundlagen JUnit Continuous Integration Testen im modellgetriebenen Kontext Informationssysteme Zielplattform und Entwicklungsumgebung Zielplattform Entwicklungsumgebung Gargoyle Anwendungsarchitektur Gargoyle-Modelle und -Workow Beispielanwendung Forensystem Domänenbeschreibung Forensystem-Modelle II Prototyping- und Analysephase 29 4 Prototyping- und Analysephase Eingrenzung der Gargoyle-Tests Wechselwirkungen mit anderen Arbeiten Überblick i

6 5 Prototypentwicklung Testfälle Testarchitektur Testausführung Testausführung über Continuous Integration Ergebnisse der Prototypingphase Abhängigkeiten zwischen Testfällen Abhängigkeiten vom Domänenmodell Trennung von Testmethoden und Testfällen Verarbeitung von Ausnahmen Abstraktion des zu testenden Systems Klassikation von Testschritten Testmuster Testklassikation Testmuster Positivtests Duplikats-Tests Not-Nullable-Tests Not-Found-Tests Verwandte Arbeiten Modellgetriebene Testgenerierung aus Sequenzdiagrammen Abgrenzung Modellbasierte Testfallbeschreibung auf Basis von Use Cases Abgrenzung Code- und Testgenerierung mit Spring Roo Abgrenzung III Konzeption und Implementierung 61 8 Konzeption und Implementierung Grobkonzeption Entwicklungsumgebung Überblick Test-Modell Testmodellierung Unit-Test-Strukturierung Testschrittklassizierung Test-Basismodell Anbindung von Fassaden Parametermappings Anwendungsbeispiel Testverwaltung Testschnittstellen ii

7 9.2.2 Testinstanzen Anwendungsbeispiel Testautomatisierung Test-Fassaden Erweiterung des Test-Basismodells EJB-Fassade Modelldetails Methoden- und Parameterklassikation Entity-Fassade EJB-Assertion-Fassade Testfallgenerierung Testkonguration im Test-Generatormodell Verwaltung von Test-Kongurationen Klassikation von Methodentests Klassikation von Testmustern Kombination von Methodentests und Testmustern Verwaltung von Methodenabhängigkeiten Zusammenfassung Testgenerierung Generierung der Testsuiten, Tests und Testschnittstellen Generierung der Testfälle und Standardwerte Generierung des In-Line Setups Testmuster zur Testfallgenerierung AttributeTest für Create-Methoden DuplicationTest für Create-Methoden NotExistsTest für Delete-Methoden Gargoyle-Test-Generator Schichtenarchitektur Generator-Workow Gargoyle-Test-Generator im MDA-Kontext IV Evaluierung und Zusammenfassung Evaluierung Vorgehensweise Modellgetriebene Methode Anwendbarkeit Testgenerierung für Metric-Wiki Testgenerierung für Reference Model Integration Testmodellierung für Systemtests Benutzerfreundlichkeit Wartbarkeit Zusammenfassung und Ausblick 131 iii

8 14.1 Zusammenfassung Ausblick Umgestaltung der aktuellen Lösung Use Case-basierte Testfälle Erweiterung der Codegeneratorkomponenten Anhang 135 A Quelltexte 137 A.1 Domäne des Forensystems A.2 Fassadenschnittstelle des Forensystems A.3 Testfälle des Test-Prototypen A.4 Testmuster des Gargoyle-Test-Generators A.5 Evaluierung der Systemtest-Fassade Glossar 149 Literaturverzeichnis 153 iv

9 Abbildungsverzeichnis 2.1 MDA-Lebenszyklus Anwendung des Fassaden-Entwurfsmusters [GHVJ05] Anwendungsfassaden für Schichtenarchitektur Schema einer Informationssystem-Architektur [Dum03] Gargoyle Komponentenarchitektur [Löw11] Gargoyle-Workow UML-Modell des Generator-Modells UML-Modell des Entity-Modells (Auszug) UML-Modell des EJB-Modells (Auszug) Domänenmodell des Forensystem-Prototypen Generator-Modell des Forensystem-Prototypen Entity-Modell des Forensystem-Prototypen EJB-Modell des Forensystem-Prototypen Generierte Softwareartefakte des Forensystem-Prototypen Gargoyle Komponentenarchitektur [Löw11] Test-relevanter Teil der Forensystem-Domäne Schichtenarchitektur des Test-Prototypen Ausführung von Tests über das Test-Servlet Fassade zur Abstraktion der Anwendungsschicht Anwendbarkeit von Testtypen auf Gargoyle-Anwendungsfassade Modellgetriebene Testgenerierung nach Javed et al. [JSW07] TestSpecicationModel nach Kiliclar (Auszug) [Kil10] Verallgemeinerter Workow des Gargoyle-Test-Generators Tests in Gargoyle-Test-Schichtenarchitektur Workow zur Generierung der Testkomponenten Teststrukturierung im Test-Modell Testschrittklassikation im Test-Modell Test-Basismodell mit abstrakter Fassade Verwendung von Test-Fassaden als Ressourcen Mapping zwischen Testschritten und Test-Fassaden Ausschnitt des Forensystem-Test-Modells Test-Schnittstelle und Parameter Standardwerte, Testfälle und Testmethoden v

10 9.11 Denition der Test-Schnittstelle und einer Testinstanz Fassaden in Gargoyle-Test-Schichtenarchitektur Workow zur Generierung der Test-Fassaden Fassadenkonguration im Test-Basismodell Instantiierung der EJB-Fassade Mapping zwischen EJB-Fassade und EJB-Modell Methodenklassikation im EJB-Fassadenmodell und Mapping auf Entity-Modell Parameterklassikation im EJB-Fassadenmodell und Mapping auf Entity-Modell EJB-Fassade des Forensystems (Auszug) Instantiierung der Entity-Fassade und Mapping zum Entity- Modell Entity-Fassadenmodell des Forensystems (Auszug) EJB-Assertion-Fassade und Mappings auf Meta-Modelle (Auszug) EJB-Assertion-Fassade des Forensystems (Auszug) Workow zur Testerzeugung Kongurationsstruktur im Test-Generatormodell Testkongurationen im Test-Generatormodell Klassikation von Methodentests Klassikation von Methodentests und Testtypen Klassikation von Testmustern Verwaltung vom Methodenabhängigkeiten für Tests Methodenabhängigkeiten im Test-Generatormodell Zusätzliche Methodenabhängigkeit für MethodUnderTest Finales Test-Generatormodell des Forensystems Generierte Methodenabhängigkeiten im Test-Modell Konguration für AttributeTest Testfall für AttributeTest im Test-Modell Konguration für DuplicationTest Testfall für DuplicationTest im Test-Modell Konguration für NotExistsTest Testfall für NotExistsTest im Test-Modell Finale Schichtenarchitektur der Gargoyle-Tests Finaler Workow des Gargoyle-Test-Generators Möglicher alternativer Einsatz des Gargoyle-Test-Generators Fehler im Gargoyle-Generator in Delete-Methoden Systemtest-Fassadenmodell Systemtest-Testmodell Systemtest-Test-Generatormodell vi

11 Quelltextverzeichnis 5.1 Beispiel für Forensystem-Testfall des Prototypen (Auszug) Test-Servlet-Klasse und Verweis auf die EJB-Komponente Aufräumen des Testsystems nach der Ausführung jedes Testfalls Trennung zwischen Testfällen und Testmethode Testen von erwarteter Auslösung von Ausnahmen (1) Testen von erwarteter Auslösung von Ausnahmen (2) Positivtest für Create-Methode Positivtest für Getter-Methode Positivtest für Update-Methode Positivtest für Delete-Methode Positivtest für GetAll-Methode Duplication-Tests Not-Null-Tests für Primärschlüssel und Wertattribute Not-Found-Tests für Primär- und Fremdschlüssel Beispiel einer Testsuite (Auszug) Beispiel eines Testfalls mit Fassadenaufrufen (Auszug) Testschnittstelle, Testfall und Standardwerte (Auszug) Testausführung und -auswertung (Auszug) Anwendungsbeispiel für Fassadenkongurationen Quelltext der Entity-Fassade des Forensystems (Auszug) Prüfmethode der EJB-Assertion-Fassade des Forensystems Fehlerbehebung für Entity-Attribut A.1 Aus dem Entity-Modell generierter Code für die Post-Entität. 137 A.2 Fassadenschnittstelle des Forensystems A.3 Testfall für Erzeugung einer Thread-Entität A.4 AttributeTest für die Create-Methode der Post-Entität A.5 DuplicationTest für die Create-Methode der Post-Entität A.6 NotExistsTest für die Delete-Methode der Post-Entität A.7 Testfallbeispiel für den Systemtest A.8 SystemTest-Fassade für den Systemtest vii

12

13 Teil I. Einleitung und Grundlagen 1

14

15 1. Einleitung Inhalt 1.1 Überblick über die Diplomarbeit Gliederung Die Anforderungen an die Wiederverwendbarkeit und Qualität von Softwareartefakten bekommen einen immer höheren Stellenwert in der Software-Engineering-Landschaft. In diesem Zusammenhang bildet die modellgetriebene Architektur (Model Driven Architecture, MDA [OMG03b]) seit einigen Jahren einen viel versprechenden Ansatz zur Softwareentwicklung. Die MDA basiert auf der Verwendung von Modellen und Generatoren sowie der Trennung von fachlichen und technischen Aspekten im Entwicklungsprozess. Der mit der Modellierung verbundene hohe Grad an Abstraktion erlaubt die Wiederverwendung von Modellen und Generatoren. Automatisch generierter Quellcode führt üblicherweise zu höherer Softwarequalität. Das plattformunabhängige Modell (platform independent model, PIM ) ist eines der zentralen Modelle modellgetriebener Architekturen. Es hat die Aufgabe, das zu entwickelnde System technologie- und implementierungsunabhängig zu beschreiben. Das plattformunabhängige Modell einer modellgetriebenen Entwicklungsumgebung ist häug auf eine bestimmte Domäne fokussiert, um eine detaillierte Modellierung von Anwendungen für diese Domäne zu ermöglichen. Als Beispiel dienen hier Domänenmodelle von Informationssystemen. Dies sind Systeme, bei denen der Fokus auf der ezienten Speicherung und Bereitstellung von Daten liegt. Die damit verbundenen Domänenmodelle bieten oftmals stark datenorientierte Sichten, die der Strukturierung und Repräsentation der zu verarbeitenden Informationen dienen. Eine Anwendung zur Modellierung und Entwicklung von Prototypen für Informationssysteme ist der Gargoyle-Codegenerator [Löw11]. Die Metamodelle des Generators dienen hauptsächlich der Darstellung von Konzepten für Datenzugri und -organisation. Andere Aspekte, wie die Denition der Architektur der späteren Anwendung, werden dagegen implizit innerhalb der Modelltransformations- und Codegenerierungsschritte realisiert. Hier liegt einer der groÿen Vorteile der MDA: Anstatt bei der Entwicklung von Anwendungen einer Domäne immer wieder die gleichen bewährten Konzepte und Muster anzuwenden, können diese einmalig modellgetrieben implementiert und wiederverwendet werden. 3

16 Testen hat in Softwareentwicklungsprozessen eine hohe Bedeutung. Daher bietet es sich bei der Anwendung der MDA an, die Auswahl und Generierung von Tests ebenfalls modellgetrieben durchzuführen. Dabei existieren verschiedene Ansätze, Tests innerhalb einer modellgetriebenen Architektur zu beschreiben bzw. zu erzeugen. Dieser noch relativ junge Bereich wird modellgetriebenes Testen (model driven testing, MDT) genannt. Die Erstellung von Tests hat einen nicht zu unterschätzenden Anteil am Gesamtaufwand innerhalb eines Softwareentwicklungsprozesses. Die automatische Erstellung von Tests kann sich zeitund kostensparend auswirken Überblick über die Diplomarbeit Zu Beginn der vorliegenden Diplomarbeit stellte sich die Frage, wie stark die modellgetriebene Testerstellung innerhalb einer MDA-Umgebung automatisiert werden kann, wenn gewisse Einschränkungen für die Anwendungsdomäne gelten. Der vorgestellte Ansatz bezieht sich dabei auf den am Lehrstuhl für Softwarekonstruktion der RWTH Aachen (SWC) entwickelten Generator zur Prototyperstellung von EJB-basierten Informationssystemen namens Gargoyle [Löw11]. Informationssysteme dienen zur Verarbeitung und Verwaltung von Daten zur Befriedigung von Informationsbedürfnissen. Mit Hilfe des Gargoyle-Generators lassen sich, basierend auf dem Domänenmodell des gewünschten Informationssystems, voll lauähige Softwareartefakte in Form von EJB-Komponenten (Enterprise Java Beans) erstellen. Diese implementieren die für Informationssysteme typischen CRUD-Funktionen (Create, Read, Update, Delete). Die Standardfunktionen eines Informationssystems können automatisch aus dem zugrundeliegenden Domänenmodell abgeleitet werden und sind modellgetrieben erzeugbar. Genauso sollte es möglich sein, die zur Software passenden Tests abzuleiten und modellgetrieben zu erzeugen. Dabei ist vollständig bekannt, wie die Architektur und Implementierung des generierten Informationssystems modellgetrieben erzeugt wurde diese Informationen sind für die Erstellung von passenden Tests unabdingbar. Auf den ersten Blick mag es fraglich erscheinen, generierten Quellcode zu testen. Dessen Semantik und Implementierung ist durch den generatorgetriebenen Ansatz bekannt und muss eigentlich nicht getestet werden. Stattdessen sollte der Fokus auf dem Testen des Codegenerators selbst liegen, da dieser für die Qualität des erstellten Programmcodes verantwortlich ist. Es gibt aber wichtige Gründe, Tests für generierte Softwareartefakte zu erzeugen: Der generierte Quellcode wird häug noch angepasst, um Verhalten abzubilden, welches in den MDA-Modellen nicht ausdrückbar ist. Deshalb wird in modellgetriebenen Softwareentwicklungsprojekten in der Regel zu einem festgelegten Zeitpunkt von der generativen bzw. modellgetriebenen Softwareerstellung zur klassischen manuellen Entwicklung übergegangen. Ab diesem Zeitpunkt sind 4

17 automatisch ausführbare Regressionstests wichtig, da damit Abweichungen vom während der Modellierung vorgesehenen Verhalten aufgedeckt werden können, die durch nachträgliche manuelle Anpassungen hervorgerufenen wurden Aufgabenstellung In dieser Diplomarbeit soll eine Methode entwickelt werden, mit der modellgetrieben Softwaretests aus den Gargoyle-Modellen speziziert und generiert werden können. Anschlieÿend ist zu evaluieren, wie weit diese generierten Tests zur Qualitätssicherung eines Softwareprojektes beitragen können. Insbesondere ist zu klären, ob eine modellgetriebene Erstellung von Tests im Hinblick auf Qualität und Aufwand im Vergleich zur manuellen Testerstellung sinnvoll ist. Im Fokus der Tests steht die vom Gargoyle-Generator erzeugte Anwendungsfassade, die die öentliche Schnittstelle des generierten Informationssystems bildet. Es sollen Testmuster gefunden werden, mit denen die einzelnen Methoden der Fassade getestet werden können. Passend zum Gargoyle-Generator soll ein Prototyp des Gargoyle-Test-Generators entwickelt werden, der die Anwendbarkeit der modellgetriebenen Testerzeugung demonstriert. Dabei ist auf eine geeignete Abstraktion des zu testenden Systems zu achten, um eine plattformunabhängige Beschreibung und Generierung von Tests zu ermöglichen. Auÿerdem soll der generierte Test-Quellcode automatisch ausgeführt werden können. Dies schlieÿt auch die Generierung von passendem Quellcode ein, der die Ausführung der Tests in einer Continuous- Integration-Umgebung [DMG07] erlaubt Ziele der Diplomarbeit Folgende Ziele leiten sich somit aus der Aufgabenstellung ab: 1. Einarbeitung in das Thema und Vergleich mit verwandten Ansätzen 2. Analyse der Anwendbarkeit von Tests für Gargoyle-Anwendungen 3. Entwurf einer modellgetriebenen Methode zur Testspezikation und Testgenerierung für Gargoyle-Anwendungen 4. Prototypische Implementierung des Gargoyle-Test-Generators 5. Evaluierung der entwickelten Lösung 5

18 1.2. Gliederung Diese Diplomarbeit ist in vier Teile gegliedert. Teil I gibt eine Einführung in das Thema und einen Überblick über die Grundlagen der hier erarbeiteten Lösung. Insbesondere stellt Abschnitt 2.5 den Gargoyle-Generator vor und führt die im Verlauf der Arbeit verwendeten Meta-Modelle ein. Kapitel 3 stellt eine Beispielanwendung vor, die als Grundlage für die Anforderungsanalyse und die Entwicklung des Prototypen des Gargoyle-Test-Generators verwendetet wurde. Der Teil II (Kapitel 4 bis 7) befasst sich mit der Prototyping-Phase und den daraus gewonnenen Erkenntnissen und Anforderungen. Dazu gehören die aus dem Prototypen abgeleiteten Testmuster (Kapitel 6) und die Analyse verwandter Arbeiten, in der ein Vergleich der hier vorgestellten Arbeit mit verschiedenen Test- und Generatoransätzen durchgeführt wird (Kapitel 7). Teil III (Kapitel 8 bis 12) beschreibt die Konzepte sowie die Implementierung der entwickelten Lösung und gibt dabei einen Überblick über den Gargoyle- Test-Generator und dessen Meta-Modelle, Modelltransformationen und Codegeneratorkomponenten. In Teil IV (Kapitel 13 bis 14) werden die Ergebnisse dieser Arbeit evaluiert. Eine Zusammenfassung mit Ausblick auf mögliche Erweiterungen und Verbesserungen des vorgestellten Ansatzes schlieÿt die Arbeit ab. 6

19 2. Grundlagen Inhalt 2.1 Model Driven Architecture Testen Informationssysteme Zielplattform und Entwicklungsumgebung Gargoyle Dieses Kapitel gibt eine Übersicht über die dieser Arbeit zugrundeliegenden Technologien und Konzepte. Dabei geht es zuerst um die Model Driven Architecture (MDA) und anschlieÿend um den Begri des Testens. Abschnitt 2.3 gibt eine kurze Übersicht zu Informationssystemen. Im Anschluÿ liefert Abschnitt 2.4 einige Informationen zur Zielplattform des Gargoyle-Test-Generators und die dabei verwendete Entwicklungsumgebung. Zuletzt wird in Abschnitt 2.5 der Gargoyle-Generator vorgestellt, auf den der zu entwickelnde Test-Generator aufsetzt Model Driven Architecture Die modellgetriebene Architektur (Model Driven Architecture, MDA) ist ein von der Object Management Group (OMG) standardisierter Softwareentwicklungsansatz, bei dem die verwendeten Meta-Modelle und Modelle im Mittelpunkt stehen [OMG03b], [KWB03]. Die OMG hat mit der Standardisierung der Unied Modeling Language (UML) einen entscheidenden Grundstein für eine einheitliche Modellierungssprache gelegt [OMG05], [Rum04], [Bal05]. Darauf aufbauend wurden mit der Meta Object Facility (MOF) und XML Metadata Interchange (XMI) die entsprechenden Grundlagen in Form von Spezikationen zur Beschreibung und zum Austausch von Metadaten (bzw. Meta-Modellen) geschaen, um eine plattformunabhängige und systemübergreifende Modellierung zu ermöglichen [OMG11a], [OMG11b]. Die MDA deniert mit Hilfe der genannten Technologien, in welcher Art und Weise Modelle in einem modellgetriebenen Softwareentwicklungsprozess zu benutzen sind. Modellgetrieben bedeutet dabei, Transformationen zwischen Modellen (Model-To-Model Transformation, M2M) bzw. zwischen Modell und Quellcode (Model-To-Text Transformation, M2T) automatisiert durchzuführen. Die 7

20 MDA diktiert dabei eine Trennung von Modellen in ein plattformunabhängiges Modell (Platform Independent Model, PIM) für die Geschäftslogik und den darauf aufsetzenden plattformspezischen Modellen (Platform Specic Model, PSM) für die Darstellung eines Systems auf der jeweiligen Zielplattform. Sie setzt auÿerdem voraus, dass die zugehörigen Transformationen zwischen PIM und PSMs deniert werden. Die MDA zielt dabei darauf ab, Softwarequalitätsmerkmale wie Portabilität, Interoperabilität und Wiederverwendbarkeit schon auf der Modellebene zu erreichen [MSUW04] Modellierungsebenen Dabei wird eine Modellarchitektur vorgegeben, die sich am Separation of Concerns-Designprinzip orientiert [Dij82]. Die MDA deniert dazu verschiedene Sichten (Viewpoints), die auf bestimmte Konzepte oder strukturelle Eigenschaften fokussiert sind und für den jeweiligen Zweck nicht benötigte Details ausblenden. In der MDA unterscheidet man dabei zwischen drei verschiedenen Sichten und den dazugehörigen Modellen der berechnungsunabhängigen Sicht mit dem Computation Independent Model (CIM), der plattformunabhängigen Sicht mit dem PIM und der plattformspezischen Sicht mit dem PSM [GPR06]. PSM Code CIM PIM PSM Code Modell Modell- Transformation M2M M2M M2M PSM M2T M2T M2T Code Das erste Modell in einem MDA-basierten Plattform 1 Plattform 2 Plattform 3 Entwicklungsprozess ist das berechnungsunabhängige Modell (Computation Independent Model, CIM). Es beschreibt das Abb. 2.1.: MDA-Lebenszyklus betrachtete Gesamtsystem sowie dessen interagierende Umgebung (system environment). Dabei wird Wert auf eine möglichst vollständige Beschreibung des Kontextes gelegt. Das CIM wird aus Sicht eines Domänenexperten modelliert. Seine Notation entspricht der Terminologie und dem Verständnis der Personen, die das System anwenden [GPR06]. Die Beschreibung des Modells kann umgangssprachlich erfolgen oder auch in einer domänenspezischen Notation. Das CIM wird oft auch als Domänenmodell bezeichnet; es bildet die Grundlage für das PIM. Die Aufgabe des plattformunabhängigen Modells (Platform Independent Model, PIM) ist die Modellierung von Systemaspekten, die so weit wie möglich technologie- und herstellerneutral abgebildet werden. Es bietet eine funktionale Sicht zur Modellierung des im CIM dokumentierten Systems, ohne auf 8

21 verwendete Technologien einzugehen. Es bildet daher eine mögliche plattformunabhängige Implementierung der Domäne ab. Aus dem PIM können ein oder mehrere plattformspezische Modelle (Platform Specic Model, PSM) erzeugt werden. Ein PSM beschreibt ein System unter Verwendung von implementierungsspezischen Konstrukten, die in einer Technologie verfügbar sind. Beispielsweise kann das PSM eine Implementierung mittels relationaler Datenbanken unter Nutzung von spezischen Begrien wie Tabelle, Spalte und Primärschlüssel beschreiben [KWB03]. Diese Sicht auf das System ist nur für Betrachter verständlich, die entsprechendes Wissen über die Zielplattform bzw. das Zielsystem besitzen. Im Gegensatz dazu sind diese Informationen für die Beschreibung der allgemeinen Struktur der Domäne im PIM irrelevant. Durch diese Trennung zwischen PIM und PSM ist das PIM auch für andere Zielplattformen wiederverwendbar. Eine Redenition der Domäne und der Anwendungslogik ist bei der Einführung neuer Technologien nicht nötig. Der Prozess der Konvertierung eines Modells in ein anderes Modell wird Modelltransformation genannt. In der MDA müssen Modelltransformationen automatisch ausführbar sein. Dies ist ein entscheidender Unterschied zwischen der MDA und herkömmlicher modellbasierter Entwicklung. Die Modelltransformationen werden dabei von Werkzeugen ausgeführt, was zur Reduzierung von Aufwänden bei der Unterstützung neuer Zielplattformen oder Technologien führt. Die selbe Forderung stellt die MDA an die Generierung von Quellcode aus PSMs auch diese Transformationen müssen automatisch ausführbar sein. Das Gebiet der Codegeneratoren bietet eine groÿe Auswahl an verfügbaren Lösungen Begrie Bei der in dieser Arbeit vorgestellten modellgetriebenen Methode werden verschiedene Ebenen betrachtet, die oftmals miteinander kombiniert auftreten. Aus diesem Grund müssen einige Begrie voneinander abgegrenzt werden: Die Meta- Modelle bilden die Grundlage des modellgetriebenen Ansatzes. Sie denieren die entsprechenden Elemente und Strukturen für die Beschreibung von Test- Fassaden und Testfällen. Darauf aufbauend beschreiben die Modelle entsprechende Instanzen dieser Meta-Modelle, also konkrete Gargoyle-Anwendungen bzw. deren Tests und die dazu benötigten Komponenten. Oftmals werden die Begrie Meta-Modell und Modell synonym verwendet, die jeweilige Bedeutung ergibt sich dabei aus dem Kontext. Modelltransformationen werden zwischen den Strukturen von Meta-Modellen deniert, um anschlieÿend zwischen Modellen ausgeführt zu werden. Dasselbe gilt für die Codegenerierung, sie wird auf der Ebene der Meta-Modelle deniert und auf Modellebene durchgeführt, um Quelltext für Tests einer konkreten Anwendung zu erzeugen. 9

22 Nutzen der MDA Die Anwendung der MDA kann in Softwareentwicklungsprozessen zu verschiedenen Verbesserungen führen. Modelltransformationen für PSMs und Codegeneratoren müssen zunächst für die jeweilige Zielplattform entwickelt werden und erfordern hoch qualizierte Entwickler. Doch sind diese Teile einer MDA- Umgebung erst einmal implementiert, können sie in vielen weiteren Entwicklungsprojekten wiederverwendet werden. Durch den hohen Automatisierungsgrad können sich Entwickler auf die Modellierung des PIMs und die damit verbundene Implementierung der Geschäftslogik konzentrieren. Sie müssen sich dabei keine Gedanken zur Implementierung von verwendeten Technologien oder Zielplattformen machen. Dadurch verspricht ein MDA-basierter Softwareentwicklungsprozess langfristig eine Steigerung der Produktivität. Die Trennung von PIM und PSM führt zu portabler und interoperabler Software, da die Geschäftslogik des PIM auch bei Technologiewechseln oder -anpassungen wiederverwendet werden kann. Im Gegenzug führt eine Änderung an der Zielplattform nicht zu Änderungen im PIM. Da die eigentliche Entwicklungsarbeit nicht im Quellcode, sondern in den Modellen vollzogen wird, entstehen keine bzw. nur geringe Synchronisationsprobleme zwischen Modellen und resultierendem Quelltext. Dadurch erhöht sich die Wartbarkeit der Software. Auÿerdem bilden die Modelle einen Teil der Dokumentation. Motorola veröentlichte im Jahre 2005 eine Studie [BLW05], die die Eekte der MDA auf hausinterne Entwicklungsprojekte bezierte. Demnach kam es durch den Einsatz von Modellsimulation, Codegenerierung und modellgetriebenem Testen zu einer Reduzierung der Arbeitsaufwände um den Faktor 2,3. Circa 33 % der Aufwände zur Testfallerstellung konnten eingespart werden. Im Bereich der Netzwerkelemente wurde der MDA-Ansatz bereits bei 9 von 12 Systemen eingesetzt, zwischen 65 % und 85 % des Quellcodes dieser Systeme konnte generiert werden. Extreme Verbesserungen gab es für Motorola bei der Beseitigung von Fehlern, die während der Integrationsphase auftreten. Normalerweise ist das Finden und Beseitigen von Fehlern zu dieser späten Phase des Entwicklungsprozesses sehr aufwändig und teuer. Durch den modellgetriebenen Ansatz konnte Motorola für diese Projektphase eine 30- bis 70-fache Reduzierung des Zeitaufwands zur Behebung von Fehlern erzielen. Insgesamt konnte Motorola in seinen modellgetriebenen Projekten eine 1,2- bis 4-fach niedrigere Fehlerrate messen. Im Bezug auf die Anzahl der erstellten Zeilen Quelltext konnte eine 2- bis 8-fache Produktivitätssteigerung erreicht werden. Aus den genannten Gründen ist die MDA ein viel versprechender Entwicklungsansatz. Der modellgetriebene Ansatz stellt allerdings hohe Anforderungen an die Entwickler, von denen ein hoher Grad an Verständnis neuer Technologien und Erfahrungen verlangt wird, um diese Art der Softwareentwicklung durchzuführen [KWB03]. 10

23 Entwurfsmuster Die Forderung nach ausführbaren Modelltransformationen bringt einen weiteren Vorteil: Der für die automatisch ausführbaren Modelltransformationen benötigte Informationsgehalt des zugrundeliegenden PIMs kann auch für die automatische Anwendung von Architektur-Entwurfsmustern (Design Patterns) verwendet werden. Anstatt diese Muster nach der Transformation manuell im Modell anzuwenden, können die dazu notwendigen Informationen und Regeln in das PIM bzw. in die Modelltransformation integriert werden. Dadurch wird den an der Modellierung beteiligten Softwarearchitekten Arbeit abgenommen und die über die Modelltransformation implementierten Funktionen zur Anwendung der Architektur-Entwurfsmuster sind wiederverwendbar und können von Experten gepegt werden. Im Folgenden werden einige ausgewählte Entwurfsmuster vorgestellt, die für diese Arbeit relevant sind. Fassade Die Fassade ist ein Entwurfsmuster aus dem Standardwerk Design Patterns Elements of Reuseable Object-Oriented Software von Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides auch als Gang of Four bekannt [GHVJ05]. Die Fassade gehört zur Klasse der strukturellen Entwurfsmuster. Clients Clients Subsystem Subsystem Fassade Abb. 2.2.: Anwendung des Fassaden-Entwurfsmusters [GHVJ05] Fassaden werden dazu genutzt, einheitliche und vereinfachte Schnittstellen zu Subsystemen zu realisieren. Verschiedene Funktionen eines Subsystems können dabei über die Fassade kombiniert und an die Komponenten des Subsystems delegiert werden. Dies kann zu einer Reduzierung der Komplexität bei der Be- 11

24 nutzung des Subsystems über die Fassade führen. Werden einzelne Funktionen des Subsystems benötigt, die nicht über die Fassade verfügbar sind, können diese trotzdem genutzt werden; eine Fassade versteckt das von ihr bereitgestellte Subsystem nicht [FFBS04]. Ein weiterer Vorteil einer Fassade ist, dass sie zur Entkopplung des Subsystems vom Rest des Systems verwendet werden kann. Erfolgt der Zugri auf das Subsystem nur über die Fassade, können Komponenten des Subsystems ausgetauscht oder das Subsystem erweitert werden, ohne dass die Schnittstelle der Fassade angepasst werden muss. Nur die Implementierung der Fassade muss an das geänderte Subsystem angepasst werden. Anwendungsfassade Eine Anwendungsfassade (application facade) ist ein von Martin Fowler konzipiertes Analysemuster [Fow99a], das zur Verbesserung der Organisation von Schichtenarchitekturen dient. Die Anwendungsfassade basiert auf dem Konzept der Fassade; allerdings wendet sie dieses in komplexeren Szenarien an. Softwarearchitekturen sind oft in Schichten unterteilt, zum Beispiel in eine Datenschicht, eine Domänenschicht und eine Anwendungsschicht. Diese unterteilt sich in eine Schicht für die Geschäftslogik und in eine Präsentationsschicht. Während die Domänenschicht komplexe Datenobjekte enthält, kann die Präsentationsschicht im Allgemeinen nur einfache Datentypen verarbeiten. Daher bedarf es einer geeigneten Abstraktion bzw. Übersetzung zwischen Domänen- und Präsentationsschicht. Eine Anwendungsfassade bietet eine logische Sicht auf die Domänenschicht, indem sie einzelne Funktionen dieser Schicht kombiniert und über Methoden verfügbar macht. Da es mehrere Betrachtungswinkel auf eine Domäne gibt, kann es auch mehrere Anwendungsfassaden geben, die verschiedene logische Sichten bereitstellen (Abbildung 2.3). Präsentationsschicht Anwendungsfassade Anwendungsfassade Geschäftslogik Komponente Datenfluss Anwendungsschicht Domänenschicht Datenschicht Abb. 2.3.: Anwendungsfassaden für Schichtenarchitektur 12

25 2.2. Testen Nach Ludewig und Lichter ist (Programm-)Testen eine dynamische und mechanisch durchgeführte Maÿnahme der analytischen Qualitätssicherung. Dies bedeutet, dass Testen eine rechnergestützte, ausführbare Form der Software- Prüfung ist. Darunter versteht man [... ] die auch mehrfache Ausführung eines Programms auf einem Rechner mit dem Ziel, Fehler zu nden [LL10]. Der ein Softwareentwicklungsprojekt begleitende Prozess des Testens sollte dabei systematisch, unter präzise denierten Randbedingungen, mit ausgewählten Testfällen und Eingaben, mit dokumentierten Ergebnissen und einer Beurteilung nach vor dem Test festgelegten Kriterien, erfolgen. Bei klassischen Vorgehensmodellen der Softwareentwicklung, wie zum Beispiel dem V-Modell, ist das Testen einer oder mehreren eigenen Phasen zugeordnet, die sich der Entwicklungsphase anschlieÿen. Werden durch das Testen Fehler aufgedeckt, kann die zeitliche Trennung von Implementierung und Fehlerbeseitigung erhöhte Aufwände erzeugen. Im Extremfall liegen zwischen der Implementierung und Fehlerkorrektur mehrere Wochen oder Monate, so dass die Entwickler sich zunächst wieder in den entsprechenden Programmteil einarbeiten müssen, um einen Defekt zu beseitigen. Neuere Softwareentwicklungsmethoden wie Extreme Programming (XP) oder Test Driven Development (TDD) fordern hingegen permanentes Testen während des gesamten Entwicklungsprozesses [BA04], [BF00], [Bec02]. Schon vor der Implementierung von Funktionen sollen entsprechende ausführbare Komponententests (Unit Tests) erstellt werden. Dies erlaubt eine direkte Rückmeldung, ob die Implementierung einer Funktion das beabsichtigte Verhalten eines Programms zur Folge hat. Hervorzuheben in agilen Softwareentwicklungsmethoden ist die Anforderung an die permanente automatisierte Durchführung von Regressionstests [SW02], zum Beispiel durch den Einsatz von Testrahmenwerken wie JUnit. Extreme Programming verlangt auÿerdem eine regelmäÿige Integration von Komponenten zu einem lauähigen Gesamtsystem, auch schon in frühen Projektstadien. Dadurch können Integrationsprobleme frühzeitig erkannt und entsprechende Gegenmaÿnahmen eingeleitet werden. Die Durchführung von Komponenten- und Integrationstests kann dabei durch Continuous Integration- Umgebungen automatisiert werden Grundlagen Tests können in funktionale und nicht-funktionale Tests unterschieden werden. Funktionale Tests prüfen dabei auf spezizierte funktionale Anforderungen, also auf das Verhalten einer Software(-komponente). Nicht-funktionale Tests prüfen dagegen nicht-funktionale Anforderungen wie Sicherheit, Gebrauchstauglichkeit oder Zuverlässigkeit. In dieser Arbeit werden Verfahren des funktionalen Testens betrachtet. 13

26 Eine andere Kategorisierung von Tests ist über das genutzte Verfahren zur Erstellung von Testfällen möglich. Hier wird zwischen Black-Box-Testen und White-Box-Testen unterschieden. Bei Black-Box-Test-Verfahren werden Testfälle nur anhand der entsprechenden Spezikation der Komponenten des zu testenden Systems (System Under Test, SUT) ohne Berücksichtigung der internen Programmstruktur erstellt. Nur das äuÿere Verhalten des Systems wird beobachtet. White-Box-Test-Verfahren greifen zur Testfallerstellung auf den Programmtext oder die innere Struktur des Systems zurück und analysieren den Kontrolluss des Testobjekts während der Testausführung [LS05]. Testfälle können hierbei aus der Programmstruktur des Testobjekts gewonnen werden. Es gibt verschiedene Arten von funktionalen Tests, um die während eines Entwicklungsprozesses entstehenden Softwareartefakte auf Erfüllung der jeweils entsprechenden Anforderungen zu prüfen. Dazu gehören zum Beispiel Komponententests, Integrationstests, Systemtests und Abnahmetests. Jeder dieser Tests prüft das zu testende System unter bestimmten Gesichtspunkten. Beim Komponententest werden die einzelnen Komponenten eines Softwaresystems erstmalig einer systematischen Prüfung unterzogen. Die Auswahl der Tests erfolgt aufgrund der äuÿeren Struktur der Komponente und der spezizierten Anforderungen. Es handelt sich hierbei also um Black-Box-Tests. Der Integrationstest prüft anschlieÿend die Interaktion zwischen Komponenten. Dabei werden immer mehr Komponenten miteinander zu gröÿeren Teilsystemen kombiniert. Dieser Vorgang wird Integration genannt. Ziel des Integrationstests ist es, Fehler in Schittstellen oder im Zusammenspiel von Komponenten aufzudecken. Ist die Integration des Gesamtsystems abgeschlossen, werden die spezizierten Anforderungen an das zu testende System im Systemtest geprüft. Dabei wird die Perspektive des Auftraggebers und der zukünftigen Anwender verwendet, um zu validieren, dass die Anforderungen an das System vollständig und angemessen umgesetzt wurden. Ein spezieller Fall des Systemtests ist der Abnahmetest, der nal durch den Auftraggeber durchgeführt wird JUnit JUnit ist ein Rahmenwerk zur automatischen Ausführung von Komponentenund Integrationstests für die Programmiersprache Java [Lin05]. Es basiert auf dem von Kent Beck entwickelten Smalltalk-Testrahmenwerk SUnit und wurde von ihm in Zusammenarbeit mit Erich Gamma auch für Java implementiert [Bec04]. Heutige agile Softwareentwicklungsmethoden setzen vermehrt auf automatisch ausführbare Tests, insbesondere Regressionstests. JUnit gilt im Bereich Java für diese Aufgabe als Standardrahmenwerk. Der groÿe Erfolg von SUnit und JUnit hat zu einer weiten Verbreitung von Test-Rahmenwerken und Implementierungen für verschiedene Programmiersprachen geführt, die unter dem 14

27 Begri xunit zusammengefasst werden [Mes07]. Diese Test-Rahmenwerke nutzen eine gemeinsame grundlegende Struktur zur Organisation und Beschreibung von Tests Continuous Integration Der Prozess des Testens und Integrierens wird beim Konzept der Continuous Integration als durchgehend durchgeführte Qualitätssicherungsmaÿnahme angesehen [DMG07]. Dies bedeutet, dass auch kleine Entwicklungsfortschritte sofort getestet und vollständig integriert werden. Somit sind kurzfristige Rückmeldungen über die Qualität des zu entwickelnden Systems möglich. Continuous Integration-Umgebungen wie Hudson [Ora12] oder Jenkins [Sma11] bieten eine Plattform, um Test und Integration für jede Änderung eines Programmes in einer Versionsverwaltungsumgebung vollautomatisch auszuführen. Entwickler müssen somit von Anfang an dafür sorgen, die bereits implementierten Teile einer Applikation lauähig zu halten. Sie erhalten durch die Continuous Integration-Umgebung eine nahezu sofortige Rückmeldung über Auswirkungen von durchgeführten Änderungen auf das Gesamtsystem Testen im modellgetriebenen Kontext In modellgetriebenen Entwicklungsumgebungen lassen sich Tests in zwei grundlegende Bereiche aufteilen. Erstens sind die in der MDA-Umgebung entwickelten Anwendungen zu testen. Zweitens werden für die MDA-Umgebung selbst Tests benötigt, um die korrekte Funktion der MDA-Komponenten sicherzustellen. Im Bereich der Anwendungsentwicklung nden nach Stahl und Völter die gleichen Klassen von Tests Anwendung, wie sie auch in klassischen Entwicklungsmethoden angewendet werden [SV05]. Dabei sollten Tests und deren Generierung so weit wie möglich in die MDA-Umgebung integriert werden. Die Modelle, die die Anwendung beschreiben, stellen die Spezikation des zu entwickelnden Systems dar und sind somit prädestiniert, auch als Grundlage für die Testgenerierung verwendet zu werden. Dies eignet sich besonders für die Erstellung der Testinfrastruktur für Komponenten- und Integrationstests. Auch können oftmals Grenzwerttests erzeugt werden, die sich aus Constraints (Einschränkungen, die gewisse Eigenschaften des Systems spezizieren) ableiten lassen. Der zweite Bereich des modellgetriebenen Testens bezieht sich auf die Domänenarchitektur, also das Testen der MDA-Umgebung selbst. Hier liegt der Fokus auf dem Testen der Meta-Modelle, Modelltransformationen und Codegeneratoren. Dies geschieht häug mit Hilfe einer Referenzimplementierung; das heiÿt, die jeweils innerhalb der MDA-Umgebung generierten Artefakte werden mit entsprechenden manuell spezizierten Ergebnissen verglichen. 15

28 2.3. Informationssysteme Unter einem Informationssystemen versteht man Systeme, die [... ] zum Ziel der optimalen Bereitstellung von Information und Kommunikation nach wirtschaftlichen Kriterien eingesetzt werden [Krc00]. Informationssysteme gehören nach Dumke [Dum03] zur Klasse der Informations- und Datenbanksysteme bzw. datenorientierten Systeme. Diese dienen zur Verarbeitung und ezienten Speicherung von Daten zur Befriedigung von Informationsbedürfnissen. Dabei kann man Informationssysteme in zwei Schichten trennen: die Datenschicht, die über ein Datenbanksystem realisiert wird, und die Anwendungsschicht, die Funktionen zur Verarbeitung und Bereitstellung von Daten implementiert (siehe Abbildung 2.4). Geschäftslogik Datenschicht Daten Informationserfassung Informationsbereitstellung Datenbankmanagementsystem Realisierungsplattform Komponente Datenfluss Abb. 2.4.: Schema einer Informationssystem-Architektur [Dum03] An ein Informationssystem gibt es verschiedene Anforderungen: Es soll die Speicherung, Aktualisierung und Archivierung umfangreicher Datenbestände ermöglichen. Dies ist die Aufgabe der Datenschicht des Informationssystems, die normalerweise über ein Datenbanksystem implementiert wird. Die darauf aufbauende Anwendungsschicht hat die Aufgabe, eziente und sinnvolle Funktionen anzubieten, um auf die in der Datenschicht gespeicherten Daten des Informationssystems zuzugreifen. Dies kann Funktionen zur Bearbeitung einzelner Datensätze bis zur Aggregation oder Analyse komplexer Datenmengen umfassen. Mit Informationssystemen wird oft der Begri der CRUD-Funktionen in Verbindung gebracht. CRUD bezeichnet die Funktionen Create, Read, Update, Delete, die die typischen Zugrie auf ein datenorientiertes System repräsentieren. 16

29 2.4. Zielplattform und Entwicklungsumgebung Dieser Abschnitt gibt eine kurze Einführung in die in dieser Arbeit verwendeten Technologien. Dabei wird zwischen der Zielplattform bzw. -architektur und der Entwicklungsumgebung unterschieden. Die verwendete Entwicklungsumgebung und Zielplattform basiert auf der durch Tobias Löwenthal in Generierung von web-basierten Prototypen für Geschäftsanwendungen [Löw11] beschriebenen Technologien. Der Gargoyle-Test-Generator ist eine direkte Erweiterung des Gargoyle-Generators. Der Einsatz der genannten Technologien hat sich beim Einsatz des Gargoyle-Generators bewährt. Daher werden diese für den Gargoyle-Test-Generator erneut verwendet Zielplattform Die vom Gargoyle-Generator und dem hier zu entwickelnden Gargoyle-Test- Generator erzeugten Applikationen basieren auf Enterprise Java Beans (EJB) und auf der Java Enterprise Edition (JavaEE) Plattform [Ora09]. EJBs sind wiederverwendbare Komponenten, die Geschäftslogik kapseln. Sie werden in einem Application Server ausgeführt, der die JavaEE-Plattform unterstützt. Dies sind zum Beispiel der Glasssh Application Server [Gla09] oder der IBM Websphere Application Server [IBM11] Entwicklungsumgebung Als MDA-Entwicklungsplattform dient die Eclipse-Entwicklungsumgebung mit dem Eclipse Modeling Framework (EMF) [Ecl12a], [Ass05], [Ecl12b], [SBMP08]. EMF ist eine Modellierungsumgebung, die alle für einen MDA-Entwicklungsprozess benötigten Komponenten bereitstellt. Das EMF bietet eine MDA-konforme Unterstützung für Modelle, Meta-Modelle und zugehörige Editoren in Form des Ecore-Meta-Modells, das auf dem MOF-Standard basiert. Zur Beschreibung der Modelltransformationen wird die funktionale Sprache Xtend verwendet, für die Codegenerierung die Templatesprache Xpand. Beide Sprachen sind in der Eclipse-Umgebung verfügbar und können durch entsprechende Werkzeuge bzw. Eclipse-Plugins (z. B. die Modeling Workow Engine (MWE)) ausgeführt werden. Die Eclipse-Umgebung unterstützt sowohl die Entwicklung der MDA-Komponenten, als auch die Ausführung der MDA-Umgebung zur modellgetriebenen Entwicklung von Anwendungen. Aus den Ecore-Meta-Modellen dieser MDA- Umgebung können ausführbare Plugins generiert werden, die die Bearbeitung von entsprechenden Modellen erlauben. Auch die Modelltransformationen und Codegeneratoren lassen sich in diese Plugins integrieren. Es entsteht eine geschlossene Applikation, mit der modellgetriebene Softwareentwicklung durchgeführt werden kann. 17

30 2.5. Gargoyle Der Gargoyle-Generator ist ein MDA-konformer Generator für EJB-basierte Informationssysteme. Er wurde 2011 am Lehrstuhl für Softwarekonstruktion der RWTH Aachen (SWC) im Zuge einer Diplomarbeit von Tobias Löwenthal entwickelt [Löw11]. Seitdem wurde der Generator stetig weiterentwickelt und unter anderem in einer Bachelorarbeit von Tristan Langer um semantische Beziehungen wie Vererbung und Komposition erweitert [Lan12] Anwendungsarchitektur Der Gargoyle-Generator erzeugt anhand eines Datenmodells voll funktionsfähige EJB-Komponenten zur Realisierung eines Informationssystems. Dabei wird eine schichtenbasierte Architektur generiert (Abbildung 2.5), die sich am Aufbau der Anwendungsfassade aus Abschnitt orientiert. Die Komponenten der Geschäftsschicht realisieren dabei die für Anwendungsfassaden typischen Funktionen, um Zugrie auf Daten des Informationssystems durchführen zu können. Die Datenschicht und die Geschäftslogik werden in einem Application Server ausgeführt. Gargoyle generiert alle Komponenten der Geschäftsschicht. Die Datenschicht wird über Komponenten des Application Servers realisiert. Unter Benutzung der Anwendungsfassade können beliebige Anwendungen auf das Informationssystem zugreifen. Die Abbildung 2.5 zeigt beispielhaft den Zugri über eine browsergestützte, auf JavaServer Pages (JSP) basierende Clientschicht. Browser EJB Action Handler Entities Application Server Datenbank Anwendungsfassade Komponente JSP Controller Actions DAO Entity Manager Kontrollfluss Clientschicht Geschäftslogik Datenschicht Abb. 2.5.: Gargoyle Komponentenarchitektur [Löw11] Die Anwendungsfassade leitet die Methodenaufrufe an die Controller-Komponenten weiter, die die eigentliche Geschäftslogik enthalten. Diese beschreibt die auf den Daten des Informationssystems auszuführenden Operationen. Die DAO- Komponenten kapseln die direkten Operationen auf der Datenschicht, die für den Zugri auf Entitäten nötig sind. Die Entitäten repräsentieren die Klassen des Datenmodells des Informationssystems und werden als persistant Entities implementiert. Der über die JavaEE-Plattform verfügbare Entity Manager sorgt für die Speicherung und den Zugri der Entitäten in der Datenschicht. 18

31 Gargoyle-Modelle und -Workow Der Gargoyle-Generator deniert einen mehrstugen Modelltransformationsprozess. Ausgehend vom Datenmodell des zu erstellenden Informationssystems werden über Modelltransformationen und entsprechende plattformspezische Modelle immer mehr Informationen bezüglich der EJB-basierten Zielplattform und der Anwendungsfassaden-Architektur erzeugt. Gargoyle-Workow «model» GeneratorModel Model-To-Model Transformation Model-To-Text Transformation «model» EntityModel «code» Domain «model» EJBGeneratorModel «model» EJBModel «code» EJBArchitecture Abb. 2.6.: Gargoyle-Workow Die Abbildung 2.6 zeigt den Gargoyle-Workow. Nach Modellierung des Datenmodells im plattformunabhängigen Generator-Modell wird dieses in das plattformspezische Entity-Modell transformiert. Es beschreibt das Domänenmodell des Informationssystems. Dazu werden die Klassen des Datenmodells durch EJB-Komponenten abgebildet. Anschlieÿend wird aus dem Entity-Modell das EJBGenerator-Modell erzeugt. Es erweitert die Entitäten um Informationen bezüglich der zu generierenden Zielarchitektur. Im letzten Modelltransformationsschritt wird das EJB-Modell aus dem EJBGenerator-Modell generiert. Es deniert die einzelnen Komponenten und Methoden der Gargoyle-Architektur. Aus dem Entity-Modell und dem EJB-Modell wird der Quellcode der Zielanwendung generiert. Dabei wird der Quellcode für das Domänenmodell aus dem Entity-Modell erzeugt (siehe Abbildung 2.6). Er implementiert die Entities- Komponente der Geschäftslogik (siehe Abbildung 2.5). Der Quellcode der restlichen Komponenten der Geschäftslogik wird aus dem EJB-Modell generiert. Dies sind die Anwendungsfassade, die Controller-Komponenten und die DAO- Komponenten für die einzelnen Entitäten des Entity-Modells. 19

32 Gargoyle-Modelle GeneratorModelRoot Generalization 1 + root + root 1 + relationships * Relationship 1..* + datatype + entity * 1 + originclass DataType type : String 1 + datatype_attribute Class name : String abstract : Boolean istoplevelelement : Boolean 1 + targetclass + incomingrelationship * Association + entity 1 name : String composition : Boolean bidirectional : Boolean 1 + attributes Attribute * «enumeration» CardinalityType multiplicity : CardinalityType targetclassrole : String name : String generatefetchmethod : Boolean partofpk : Boolean one2one one2many many2one many2many originclassrole : String targetordered : Boolean originordered : Boolean Abb. 2.7.: UML-Modell des Generator-Modells Das Generator-Modell ist das plattformunabhängige Modell des Gargoyle-Generators. Es deniert das Datenmodell des zu erzeugenden Informationssystems und hat eine starke Ähnlichkeit zu Klassendiagrammen. Abbildung 2.7 zeigt das Meta-Modell des Generator-Modells. Es deniert die grundlegenden Konstrukte zur Modellierung von objektorientierten Datenstrukturen in Form von Klassen, Attributen und Assoziationen. Klassen können als Top-Level-Element markiert werden. Dies bedeutet, dass das resultierende Informationssystem Methoden bereitstellt, um Objekte dieser Klasse zu erzeugen, ohne dass sie in einer Kompositionsbeziehung zu anderen Objekten stehen müssen. Attribute können als Primärschlüssel markiert werden, anhand derer Objekte eindeutig identiziert werden können. Assoziationen können verschiedene Kardinalitäten besitzen und auÿerdem Kompositions- und Vererbungsbeziehungen beschreiben. Das Entity-Modell in Abbildung 2.8 bildet das Datenmodell des Generator- Modells in Form von Entitäten und Attributen ab. Assoziationen werden im Entity-Modell ebenfalls als Attribute dargestellt, die mit der entsprechenden Kardinalität annotiert sind. Kompositionen werden durch geeignet markierte Attribute repräsentiert. Zusätzlich werden entsprechende Fremdschlüssel hinzugefügt, die eine eindeutige Identizierung von Entitäten auch über mehrere Kompositionsebenen hinweg erlauben. Vererbungsbeziehungen zwischen Klassen des Generator-Modells werden im Entity-Modell aufgelöst: Alle Attribute 20

33 EntityModelRoot One2Many Many2One Many2Many mainpackagename : String mappedbyattributename : String 1 - root + src * * - packages EntityPackage subpackagename : String 1 - package * - contents EntityPackageContent name : String getfullpackagename () Entity isabstract () issubclass () issuperclass () getsuperclassname () iscontained () iscontainedby () + mappedby 0..1 Attribute name : String type : String partofpk : Boolean composition : Boolean ordered : Boolean generatefetchnq : Boolean + attribute inversereferencename : String * hasx2manyannotation () hasannotationmappedby () compositionattribute + entity * 1 * ForeignKey + origin + attribute * Annotation 1 + annotations + mappedby PartOfID src * One2One mappedbyattributename : String 1 + attributeorigin * InheritedAttribute Abb. 2.8.: UML-Modell des Entity-Modells (Auszug) der Vaterentität werden als abgeleitetes Attribut in der abgeleiteten Entität eingefügt, ebenfalls erbt die abgeleitete Entität alle Fremdschlüssel der Vaterentität. Das Entity-Modell gilt bereits als plattformspezisches Modell, da es einige EJB-spezische Details modelliert. Auf das EJB-Generator-Modell wird an dieser Stelle nicht weiter eingegangen. Es dient zur Konguration von Details der im EJB-Modell modellierten Architektur und ist für diese Arbeit nicht relevant. Das EJB-Modell, das auszugsweise in Abbildung 2.9 auf Seite 22 dargestellt ist, stellt das Informationssystem im Kontext der zu generierenden Architektur dar. Es deniert die für die Entitäten und Attribute verwendeten Datentypen und die Methoden für die Anwendungsfassade und die Controller- und Datenabstraktionskomponenten. 21

34 EJBModelRoot exceptionspackage : String 1 - root + src * - packages BeanPackage packagename : String 1 - package * - beans AbstractBean name : String 1 + bean 1 * + src + attributetypes src * + primitives * + entitytypes Entity + entity 1 + src * 1 + entity * + src ManagementMethod + returntype SameTypeAsAttribute getname ( ) PrimitiveType primitivename : String getname ( ) TypeForEntity getname ( ) TypeApplication 1 aslist : Boolean gettypewithmodifier ( ) getname ( ) + type 1 * - methods Method name : String getreturntypeasstring ( ) 1 + src 1 + method + parameter_entityattribute * + parameter Parameter name : String 1 FacadeMethod getreturntypeasstring ( ) * + facademethods 1 + controllermethod ControllerMethod entity : Entity Abb. 2.9.: UML-Modell des EJB-Modells (Auszug) 22

35 3. Beispielanwendung Forensystem Inhalt 3.1 Domänenbeschreibung Forensystem-Modelle Um Ideen und Konzepte zur modellgetriebenen Erzeugung von Testfällen zu evaluieren, wurde mit dem Gargoyle-Generator (siehe Kapitel 2.5) eine Beispielanwendung erstellt. An diese Anwendung gab es die grundlegende Anforderung, möglichst viele verschiedene Kombinationen von Klassen, Attributen und Assoziationen des Domänen-Meta-Modells zu verwenden. Somit konnten während der Analysephase verschiedene Testmuster aus der Beispielanwendung abgeleitet werden. Während der Implementierungsphase diente die Anwendung auÿerdem als Referenzimplementierung zum Testen des Gargoyle-Test-Generators. Forum title : String * - forum - forum 1 - forum 1 threads - threads * - threads * Thread threadtitle : String threadid : int locked : boolean forumusers userthreads 1 - thread * - users User name : String mailaddress : String 1 - owner - owner 1 - owner 1 forumposts posts Poll question : String options : String userdetails details userposts UserDetails detailsid : int firstname : String lastname : String birthday : String - posts * - posts * * - posts Post postid : int text : String Abb. 3.1.: Domänenmodell des Forensystem-Prototypen 23

36 Für die Beispielanwendung wurde das in Abbildung 3.1 als Domänenmodell dargestellte Forensystem verwendet. Es nutzt das vom Gargoyle-Generator bereitgestellte Vererbungskonzept, Kompositionsbeziehungen und verschiedene Arten von Assoziationstypen (One2One, One2Many, Many2One, Many2Many). Ein wichtiges Detail ist die mehrstuge Komposition zwischen den Entitäten Forum, Thread und Post, da diese später bei der Auösung von Abhängigkeiten zwischen Primär- und Fremdschlüsseln bei der Testausführung eine Rolle spielt (siehe dazu Kapitel 6). Trotzdem ist das Domänenmodell mit seinen sechs Klassen vergleichsweise kompakt und verursachte dadurch keine unnötigen Aufwände bei der Evaluierung und manuellen Prototyperstellung der Tests Domänenbeschreibung Die in der Beispielanwendung implementierte Anwendung ist ein Informationssystem zur Verwaltung von Diskussionsforen. Diskussionsforen sind weit verbreitet; daher können die grundlegenden Funktionen eines solchen Systems als allgemein bekannt angenommen werden. Dies war bei Diskussionen während der Analyse-, Konzeptions- und Implementierungsphase sehr hilfreich. Mit dem Forensystem können zum Beispiel Foren und Benutzer angelegt, neue Diskussionen in einzelnen Foren erzeugt oder neue Beiträge zu bestehenden Diskussionen hinzugefügt werden. Dieser Abschnitt gibt eine kurze Übersicht über die modellierte Domäne und die in ihr denierten Klassen, Attribute und Assoziationen. Ein Diskussionsforum (Forum) ist eine der Klassen des Forensystems es hat einen Titel (Attribut title), über den das Forum eindeutig identiziert werden kann. Ein Forum ist ein sogenanntes Top-Level-Element (siehe Abschnitt 2.5), es hängt also von keiner Kompositionsbeziehung ab und gehört somit zu den Wurzelelementen des Forensystems. Je Forum gibt es eine beliebige Anzahl Diskussionen (Thread). Zwischen Forum und Thread besteht eine Kompositionsbeziehung. Das bedeutet, dass eine Diskussion immer genau in einem Forum enthalten sein muss. Wird ein Forum gelöscht, dann auch alle im Forum enthaltenen Thread-Elemente. Eine weiteres Top-Level-Element des Forensystems sind die Benutzer (User). Diese werden über ihren Benutzernamen (Attribut name) identiziert; zusätzlich besitzen sie eine Mailaddresse (Attribut mailaddress), die nicht leer sein darf. Jedem Benutzer können weitere Details (UserDetails) zugeordnet werden (Komposition userdetails). Diese werden über ihren Primärschlüssel (Attribut detailsid) identiziert und können Angaben über Vornamen, Nachnamen und Geburtstag eines Benutzers speichern (rstname, lastname, birthday). Benutzer können mit einem oder mehreren Foren assoziiert werden (Assoziation forumusers). Diese Assoziation soll semantisch der Berechtigung eines Benut- 24

37 zers entsprechen, im Forum Beiträge anzulegen, an Diskussionen teilzunehmen etc. Diese gewünschte Einschränkung kann innerhalb des Gargoyle-Generators nicht modelliert werden, sondern muss nach der Generierung des Systems manuell implementiert werden. Thread und Poll repräsentieren die Diskussionen bzw. Umfragen innerhalb eines Forums. Poll ist dabei eine Spezialisierung von Thread und erbt alle Attribute der Thread-Klasse. Dies gilt auch für den Primärschlüssel threadid, über den Objekte beider Klassen eindeutig identiziert werden können. Thread und Poll besitzen zwei Attribute threadtitle und locked, Poll zusätzlich die Attribute question (die Frage der Umfrage) und options (die vorgegebenen Antwortmöglichkeiten). Das boolesche Attribut locked soll in der Zielanwendung steuern, ob neue Beiträge zur Diskussion hinzugefügt werden können oder nicht auch diese Einschränkung ist in der generierten Anwendung noch nicht implementiert und muss manuell implementiert werden. Die Assoziation userthreads beschreibt den erstellenden Benutzer (owner) einer Diskussion. In entgegengesetzter Richtung (threads) beschreibt die Assoziation die Menge aller erstellten Diskussionen bzw. Umfragen des aktuellen Benutzers. Die Entität Post beschreibt entsprechende Beiträge innerhalb einer Diskussion oder Umfrage. Der Primärschlüssel für einen Beitrag ist postid, der Inhalt eines Beitrags wird über das Attribut text repräsentiert. Die Assoziation userposts beschreibt die Menge aller erstellten Beiträge eines Benutzers (Assoziationsrichtung posts) bzw. den Ersteller eines Beitrags (Assoziationsrichtung owner). Die Assoziation forumposts zwischen Forum und Post ist ein Sonderfall: Beide Assoziationsrichtungen können transitiv über die Kompositionsbeziehungen zwischen Forum und Thread bzw. zwischen Thread und Post aufgelöst werden. Die Assoziationsrichtung posts beschreibt die Menge aller Beiträge in allen Diskussionen bzw. Umfragen eines Forums. Die Rückrichtung forum der Assoziation bildet das Forum ab, das den Thread enthält, der den betreenden Post enthält. Auch diese Anwendungslogik muss nachträglich manuell implementiert werden Forensystem-Modelle Dem in Abschnitt vorgestellten Generator-Workow folgend zeigt dieser Abschnitt am Beispiel des Forensystems, welche Details in den einzelnen Gargoyle-Modellen modelliert wurden. Im Generator-Modell wurde die Domäne des Forensystems modelliert, die dem in Abbildung 3.1 abgebildeten UML-Modell entspricht. Zusätzlich wurden bestimmte Attribute jeder Klasse als Primärschlüssel markiert; das heiÿt, diese Attribute können zur eindeutigen Identizierung einer Objekts der betreenden Klasse verwendet werden. Abbildung 3.2 zeigt einen Ausschnitt des Editors für 25

38 Abb. 3.2.: Generator-Modell des Forensystem-Prototypen das Gargoyle-Generator-Modell des modellierten Forensystems. Im unteren Teil sieht man die Generatorattribute für die Klasse Forum z. B. das Attribut Is Top Level Element, das den bereits erwähnten Status der Klasse als Top-Level- Element beeinusst. Im oberen Teil der Abbildung sind die dem Domänenmodell entsprechenden Attribute und Assoziationen der Klassen Forum und Thread sichtbar. Abb. 3.3.: Entity-Modell des Forensystem-Prototypen 26

39 Das aus dem Generator-Modell durch Modelltransformation erzeugte Entity- Modell des Forensystems ist in Abbildung 3.3 zu sehen. Während der Transformation wurde für jede der im Generator-Modell modellierten Klassen eine Entität im Entity-Modell erzeugt, Klassenattribute und -assoziationen wurden auf Attribute der jeweiligen Entität abgebildet. Zusätzlich wurden neue Attribute und Named Queries erzeugt, die Informationen zur Speicherung und zum Datenzugri auf die jeweilige Entität innerhalb des Informationssystems und für ihre spätere technische Realisierung als EJB-Komponenten (siehe Abschnitt 2.5.1) bereitstellen. Beispielsweise sind in der Abbildung 3.3 drei verschiedene Named Queries zu erkennen: getallforum ist ein sogenannter Top-Level-Query und beschreibt somit den Zugri auf die Menge aller Foren des Forensystems. Die Named Queries get- ForumByTitle und getthreadbythreadidandtitle beschreiben den Zugri auf eine Entität vom Typ Forum bzw. Thread, die über ihre Primär- und Fremdschlüssel eindeutig identiziert wird. Aus dem Entity-Modell des Forensystems wurde der Domänen-Quellcode generiert. Dieser realisiert die Operationen zur Manipulation der einzelnen Entitäten des Domänenmodells. Der generierte Quellcode für die Post-Entität ist im Anhang im Quelltext A.1 abgebildet. Anschlieÿend wurde das EJB-Generator-Modell per Modelltransformation aus dem Entity-Modell erzeugt. Es erweitert die Entitäten des Entity-Modells um zusätzliche Informationen. Beispielsweise deniert es spezielle Methoden für jede Entität (Exists-, Fetch- und List-All-Methoden), die später in der Zielarchitektur für den Datenzugri verwendet werden können. Das anschlieÿend erzeugte EJB-Modell beschreibt das generierte Informationssystem mit den verschiedenen Komponenten der Gargoyle-Anwendungsfassade (siehe Abschnitt 2.5.1). Die Abbildung 3.4 zeigt einen Auszug des EJB-Modells des Forensystems. Zu sehen sind verschiedene Details zur Entität Poll der obere Teil zeigt die Methodenkongurationen für das zu generierende Data Abstraction Object (DAO), der mittlere Teil der Abbildung zeigt die Methodenkon- gurationen für die zu generierende Controller-Komponente. Der untere Teil der Abbildung deniert die Methoden der Fassade des Systems. Im letzten Schritt der Generierung des Prototypen für das Forensystem wurde der Quellcode aus dem EJB-Modell erzeugt. Abbildung 3.5 zeigt eine Übersicht über die generierten Quelltextartefakte. Zusätzlich zeigt der Quelltext A.2 im Anhang die Java-Schnittstelle der generierten Fassade des Forensystems. 27

40 Abb. 3.4.: EJB-Modell des Forensystem-Prototypen Abb. 3.5.: Generierte Softwareartefakte des Forensystem-Prototypen 28

41 Teil II. Prototyping- und Analysephase 29

42

43 4. Prototyping- und Analysephase Inhalt 4.1 Eingrenzung der Gargoyle-Tests Wechselwirkungen mit anderen Arbeiten Überblick Die Möglichkeiten der Testgenerierung für den Gargoyle-Generator und die genauen Anforderungen an den Test-Generator waren zu Beginn der Diplomarbeit noch nicht ausreichend bestimmt. Die Erstellung eines Test-Prototyps unter Verwendung des in Kapitel 3 vorgestellten Forensystems bot die Möglichkeit, die Anwendbarkeit der geplanten Funktionen zu demonstrieren und Anforderungen zu präzisieren. Aufbauend auf den erstellten Prototypen wurde evaluiert, wie eine geeignete Abstraktion des zu testenden Systems (System Under Test, SUT) und eine davon unabhängige Beschreibung von ausführbaren Testfällen realisiert werden könnte. Im weiteren Verlauf der Diplomarbeit diente der Test-Prototyp auÿerdem als Referenzimplementierung für den zu entwickelnden Gargoyle-Test-Generator. Dabei gab es zu Beginn grundlegende Fragen zu klären, auf die in den vorliegenden Abschnitten kurz eingegangen wird: Für welche Bereiche bzw. Komponenten der mit dem Gargoyle-Generator erstellten Anwendungen ist die Generierung von Tests sinnvoll? Welche Testkategorien (siehe Abschnitt 2.2.1) sollen damit abgedeckt bzw. unterstützt werden? Aus welchen Informationen der Gargoyle-Modelle sind diese Tests ableitbar? Wie können diese Tests automatisiert ausgeführt werden? Nach der erfolgreichen Klärung der obigen Fragen wurden Möglichkeiten zur Testabstraktion evaluiert. Diese Betrachtung warf weitere Fragen auf, die für die anschlieÿende Entwurfs- und Implementierungsphase relevant waren: Welche Komponenten und Infrastruktur muss ein geeignetes Test-Modell beschreiben, um daraus ausführbare Tests generieren zu können? 31

44 Lassen sich die Einzelschritte von Testfällen in geeigneter Weise abstrahieren und klassizieren? Lässt sich das SUT abstrahieren, so dass das Test-Modell unabhängig vom zu testenden System verwendet werden kann? Der Groÿteil dieser zweiten Evaluierungsphase wurde anhand der Erfahrungen mit dem Test-Prototypen nur noch informell durchgeführt und nicht mehr prototypisch implementiert. Stattdessen ossen die Ideen direkt in die anschlieÿende Entwurfs- und Implementierungsphase ein, die im Teil III dieser Arbeit ab Seite 63 beschrieben wird Eingrenzung der Gargoyle-Tests Abbildung 4.1 zeigt die aus Abschnitt 2.5 bekannte Gargoyle-Schichtenarchitektur. Zu Beginn der Diplomarbeit wurde festgelegt, den Fokus auf die Erzeugung von Integrationstests unter Nutzung der Anwendungsfassade zu legen. Diese bildet die äuÿere Schnittstelle des Systems, die Ausführung von Tests auf der Anwendungsfassade simuliert also die Nutzung durch die Clientschicht. Tests auf der Anwendungsfassade sind dazu geeignet, die korrekte Interaktion zwischen Controller-, DAO- und Entity-Komponenten und der darunter liegenden Datenschicht zu prüfen. Dies kann sowohl funktionale (Regressions-)Tests umfassen, als auch Installationstests, die sicherstellen, dass ein System bei Auslieferung vollständig installiert ist, alle Komponenten verfügbar sind und untereinander kommunizieren können. EJB Entities Application Server Datenbank Anwendungsfassade Komponente Controller DAO Entity Manager Kontrollfluss Geschäftslogik Datenschicht Abb. 4.1.: Gargoyle Komponentenarchitektur [Löw11] Dagegen sind Komponententests für einzelne Controller-, DAO- oder Entity- Komponenten nur schwer realisierbar. Die einzelnen Komponenten greifen zur Realisierung ihrer Funktionen auf den Application Server zurück, zum Beispiel auf den Entity-Manager oder zur Interaktion mit anderen Komponenten. Dadurch können sie nur mit hohem Aufwand und Änderungen am produktiven Quellcode isoliert getestet werden. Folglich müssen bereits einige der Komponenten miteinander integriert sein, um sinnvolle Tests ausführen zu können, deren Erstellung auch wirtschaftlich vertretbar ist. Auf der anderen Seite ist 32

45 die ursprüngliche Implementierung der einzelnen Komponenten und ihre Interaktionen miteinander hinreichend bekannt, da ihre Implementierung durch den Generator erfolgt. Dadurch können spezielle Testfälle für die Prüfung bestimmter Funktionen von Komponenten auch über die Anwendungsfassade ausgeführt werden. Diese Tests haben zumindest teilweise den Charakter von White-Box- Tests. Im Kontext des Extreme Programming [BA04] wird in diesem Zusammenhang auch von Grey-Box-Tests gesprochen. Die hier betrachteten Tests beziehen sich auf die Anwendungsseite der zu entwickelnden MDA-Umgebung. Gleichzeitig ist mit Hilfe der Tests eine Validierung der Domänenarchitektur möglich, da damit das korrekte Verhalten der Generatoren für die Anwendungslogik überprüft werden kann [SV05] Wechselwirkungen mit anderen Arbeiten Während der Prototypentwicklung war der Gargoyle-Test-Generator noch nicht voll funktionsfähig. Einzelne Konzepte zur Vererbung, zum Aufbau der Schnittstellen von CRUD-Methoden komponierter Entitäten und die Methoden zur Verwaltung von Assoziationen waren unvollständig oder noch nicht implementiert. Die nötigen Anpassungen und Erweiterungen wurden durch Tristan Langer im Umfang einer Bachelorarbeit parallel zur vorliegenden Diplomarbeit durchgeführt [Lan12]. Ein Teil der fehlenden Methoden wurde für die Erstellung des Test-Prototypen händisch im Forensystem implementiert, um das geplante Verhalten abzubilden. Allerdings waren dadurch nicht alle Schnittstellen der Prototyp-Implementierung konform zur späteren, durch den fertigen Gargoyle-Generator erstellten Version des Forensystems. Dies hatte Auswirkungen auf die Art und Vollständigkeit der im weiteren Verlauf dieser Arbeit aus dem Prototypen abgeleiteten Testmuster und die darauf aufbauende modellgetriebene Methode zur Testgenerierung. Weitere Wechselwirkungen gab es mit der Bachelorarbeit von Michael Krein, die sich mit der Generierung von Systemtests für Gargoyle-Anwendungen befasste [Kre12]. Während der Entwicklung der frühen Konzepte zur Testabstraktion mussten die von ihm betrachteten Teststrategien ebenfalls berücksichtigt werden. Dies erlaubt eine spätere Integration der Systemtestgenerierung in die hier vorgestellte modellgetriebene Methode Überblick Die folgenden Kapitel beschreiben die Prototypingphase und die daraus gewonnenen Ergebnisse. Kapitel 5 geht auf die Entwicklung des Test-Prototyps ein. Die hier erarbeiteten Konzepte präzisieren zugleich die Anforderungen für die anschlieÿende Entwurfs- und Implementierungsphase. Anschlieÿend beschreibt 33

46 Kapitel 6 einige für den Gargoyle-Test-Generator geeignete Muster von Testfällen, die aus dem Prototypen abgeleitet werden konnten. In Kapitel 7 wird der in dieser Diplomarbeit vorgestellte Ansatz mit anderen modellbasierten bzw. modellgetriebenen Testkonzepten verglichen und eine Abgrenzung der hier vorgestellten Lösung vorgenommen. 34

47 5. Prototypentwicklung Inhalt 5.1 Testfälle Testarchitektur Ergebnisse der Prototypingphase Mit der Prototypentwicklung wurden verschiedene Ziele verfolgt, die sich in zwei Bereiche aufteilen: Auf der einen Seite galt es, Gargoyle-spezische Tests zu realisieren und zu evaluieren. Auf der anderen Seite sollte eine geeignete Abstraktion des zu testenden Systems gefunden werden, um zumindest Teile des zu entwickelnden Test-Generators auch für andere Systeme wiederverwenden zu können. Auÿerdem sollte eine möglichst vollständige Testinfrastruktur implementiert werden, um die Machbarkeit des für MDA-Umgebungen typischen hohen Automatisierungsgrades zu demonstrieren. Die prototypische Implementierung von Integrationstests gegen die Gargoyle- Anwendungsfassade erfolgte unter Verwendung des Forensystems aus Kapitel 3. Im Quelltext A.2 des Anhangs ist die Schnittstelle der Forensystem-Fassade abgebildet, die die Schnittstelle zum zu testenden System bildet Testfälle In der Prototypingphase wurden verschiedene Testfälle implementiert, die aus dem Domänenmodell und unter Kenntnis der entsprechenden Realisierung desselben im generierten Informationssystem ableitbar waren. Zur Implementierung der Testfälle wurde das JUnit-Rahmenwerk verwendet (siehe Grundlagen 2.2.2). Der Quelltext 5.1 zeigt einen Auszug eines Tests der Create-Methode für die Thread-Entität des Forensystems. Der komplette Quelltext der Methode ndet sich in Anhang A.3. Der Testfall wurde aus dem Forensystem-Domänenmodell abgeleitet; Abbildung 5.1 zeigt den für den Test relevanten Teil des Domänenmodells. Forum und Thread stehen in einer Kompositionsbeziehung zueinander. zwischen Forum und User bzw. User und Thread bestehen normale Assoziationsbeziehungen. 35

48 Quelltext 5.1: Beispiel für Forensystem-Testfall des Prototypen (Auszug) 2 p u b l i c void testcreatenewthreadforforum ( ) { 3 /... / 4 forumfacade. createforum ( forumtitle ) ; 5 forumfacade. c r e a t e U s e r ( username, usermailaddress ) ; 6 forumassociationsfacade. addusertoforum ( forumtitle, username ) ; 7 8 forumassociationsfacade. createnewthreadforforum ( forumtitle, username, 9 threadid, t h r e a d T i t l e, threadlocked ) ; Forum forum = forumfacade. getforumbytitle ( forumtitle ) ; 12 Thread thread = 13 forumfacade. getthreadbythreadidandtitle ( threadid, forumtitle ) ; 14 User u s e r = forumfacade. getuserbyname ( username ) ; Assert. a s s e r t E q u a l s ( " Invalid thread id!", threadid, 17 thread. getthreadid ( ) ) ; 18 Assert. a s s e r t E q u a l s ( " Invalid thread title!", t h r e a d T i t l e, 19 thread. g e t T i t l e ( ) ) ; 20 Assert. a s s e r t E q u a l s ( " Invalid thread locked!", threadlocked, 21 thread. getlocked ( ) ) ; 22 } Forum - forum title : String 1 * - forum * - users threads userthreads - threads * - threads * Thread threadtitle : String threadid : int locked : boolean User - owner name : String 1 mailaddress : String Abb. 5.1.: Test-relevanter Teil der Forensystem-Domäne Die zu testende Methode wird im Quelltextbeispiel in der Zeile 8 aufgerufen. Das für diesen Methodenaufruf aufgrund der Kompositionsbeziehung zwischen Forum und Thread benötigte Vaterelement in Form einer Forum-Entität wird durch den vorherigen Methodenaufruf in Zeile 4 erzeugt. Auÿerdem wird eine User-Entität erzeugt und mit der Forum-Entität verknüpft (Zeilen 5 bis 6). Die Zeilen 11 bis 21 des Quelltextbeispiels dienen zur Überprüfung der erwarteten Ergebnisse. Dazu werden zuerst die am Testfall beteiligten Entitäten des Domänenmodells über die Anwendungsfassade aufgelöst (Zeilen 11 bis 14). Anschlieÿend werden die einzelnen Attribute und Assoziationen der Domänenobjekte validiert. Die Zeilen 16 bis 21 zeigen einen kleinen Ausschnitt der möglichen Prüfoperationen. 36

49 5.2. Testarchitektur Das Testen von EJB-Komponenten kann nur im Kontext eines Application Servers durchgeführt werden, da dieser für die Kommunikation zwischen den einzelnen Komponenten und den Zugri auf die Komponenten von auÿen zuständig ist. Die Tests innerhalb einer Komponente auszuführen ist nicht empfehlenswert, da diese Art der Interaktion der Tests mit dem zu testenden System nicht mit der späteren produktiven Verwendung der Komponente im Anwendungskontext übereinstimmt. Aus diesem Grund werden die in Abbildung 5.2 dargestellten Komponenten der Testschicht verwendet. Dabei handelt es sich um ein Test-Servlet und einen Test- Wrapper. Das Test-Servlet läuft im Kontext des Application Servers. Es enthält die Testfälle und kommuniziert mit der zu testenden Anwendungsfassade. Der Test- Wrapper wird über eine Continuous Integration-Umgebung ausgeführt. Er greift als Client auf die Test-Servlet im Application Server zu. Sie dient zur Ausführung und Auswertung der Testfälle des Test- Servlets. Browser EJB Entities Application Server Datenbank Test-Wrapper (HtmlUnit) Test-Servlet (JUnit) Anwendungsfassade Komponente Controller DAO Entity Manager Kontrollfluss Testschicht Gargoyle-Anwendung Abb. 5.2.: Schichtenarchitektur des Test-Prototypen Testausführung Um das beschriebene Problem des Testausführungkontexts zu umgehen, werden die Tests durch ein Test-Servlet ausgeführt. Es wird über JavaEE-Annotationen während der Ausführung im Application Server mit den zu testenden Komponenten bekanntgemacht und interagiert während der Testausführung mit diesen. Quelltext 5.2 zeigt einen Ausschnitt der Test-Servlet-Klasse mit dem entsprechenden Verweis auf die EJB-Komponente des Forensystems, die die Anwendungsfassade bereitstellt. Das annotierte Attribut forumfacade in Zeile 2 des Quelltextbeispiels wird durch den Application Server mit einer entsprechenden Instanz der Anwendungsfassaden-Komponente initialisiert und kann anschlieÿend zur Ausführung von Methoden der Anwendungsfassade benutzt werden. Abbildung 5.3 zeigt eine Beispielausgabe der Testausführung über das Test-Servlet. 37

50 Quelltext 5.2: Test-Servlet-Klasse und Verweis auf die EJB-Komponente 1 p u b l i c c l a s s T e s t S e r v l e t extends H t t p S e r v l e t { p r i v a t e ForumFacadeLocal forumfacade ; 3 p r i v a t e s t a t i c ForumFacadeLocal ForumFacade ; 4 5 p u b l i c s t a t i c ForumFacadeLocal ForumFacade ( ) { 6 r e t u r n ForumFacade ; 7 } Abb. 5.3.: Ausführung von Tests über das Test-Servlet Testausführung über Continuous Integration Das beschriebene Test-Servlet wird zusammen mit der zu testenden Applikation im Application Server geladen und ist über eine URL für Clientanwendungen aufrufbar. Somit können einzelne in der Test-Servlet-Komponente enthaltene Testfälle ausgeführt und ihr Ergebnis ausgewertet werden. Um nun über die Continuous Integration-Umgebung alle Testfälle der Test- Servlet-Komponente automatisiert zu starten und auszuwerten, wird die Test- Wrapper-Komponente verwendet. Diese übernimmt die Rolle einer Clientanwendung, die auf den Application Server zugreift und die Methoden des Test- Servlets aufruft. Sie basiert auf HtmlUnit, einem Test-Rahmenwerk, mit dem browserbasierte Tests ausgeführt werden können [Gar11]. Damit der Test-Wrapper die Testfälle des Test-Servlets ausführen kann, werden für alle Testfälle des Test-Servlets entsprechende Testfälle im Test-Wrapper deniert. Jeder dieser Testfälle ruft nun den korrespondierenden Testfall des Test-Servlets auf und wertet dessen Ergebnis aus. Ist ein Test des Test-Servlets erfolgreich, so wird auch für den entsprechenden Test-Wrapper-Testfall Erfolg 38

51 gemeldet. Schlägt der Test im Test-Servlet fehl, wird auch für den Test des Test-Wrappers ein Fehlschlag gemeldet. Die Continuous Integration-Umgebung startet die Testausführung der Test- Wrapper-Komponente und wertet anschlieÿend das Ergebnis der Testfälle aus. Das in der Continuous Integration-Umgebung dargestellte Testergebnis stimmt aufgrund der Abhängigkeiten zwischen den Test-Wrapper- und den Test-Servlet- Tests mit den Ergebnissen der Tests auf der Anwendungsfassade überein. Kombiniert mit einer automatisierten Überwachung der Versionsverwaltung, anschlieÿender Neuerstellung und Integration der einzelnen Anwendungs- und Test-Komponenten und Bereitstellung der Komponenten (deployment) im Application Server können so alle Tests vollautomatisch ausgeführt werden, sobald die Anwendung oder deren Tests geändert wurden. Während der Prototyperstellung wurde die Machbarkeit der vorgestellten Methode durch Implementierung einer auf dem Hudson Continuous Integration Server [Ora12] basierenden Integrationsumgebung demonstriert Ergebnisse der Prototypingphase Durch die Implementierung und Evaluierung des Test-Prototypen konnten verschiedene Ansätze und Lösungen erarbeitet werden, die in die Entwurfs- und Implementierungsphase einossen. Einige dieser Konzepte werden in diesem Abschnitt vorgestellt Abhängigkeiten zwischen Testfällen Ein Problem bei der Durchführung mehrerer Tests sind mögliche Seiteneekte, die Tests aufeinander haben können. Prüft zum Beispiel ein Testfall das erfolgreiche Anlegen einer Entität, könnte ein anschlieÿend ausgeführter Test fehlschlagen, wenn er ebenfalls versucht, eine Entität mit gleichem Typ und Attributen anzulegen. Um dieses Problem zu umgehen, wird die Datenbank des Informationssystems nach jedem Testfall komplett geleert. Dies entspricht dem Testmuster Table Truncation Teardown aus dem Buch xunit Test Patterns von Gerard Meszaros [Mes07]. Dazu wird die vom JUnit-Rahmenwerk für jede Testklasse bereitgestellte Teardown-Methode verwendet. Setup- bzw. Teardown-Methoden werden vor bzw. nach der Ausführung jedes einzelnen Testfalls aufgerufen. Der vorliegende Prototyp nutzt in der Teardown-Methode jeder Testklasse eine Service-Klasse, um eine Verbindung zur Datenbank des Systems aufzubauen und alle Inhalte der Datenbanktabellen des Informationssystems zu leeren (siehe Quelltext 5.3). Dies stellt sicher, dass jeder Testfall auf einer leeren Instanz des Informationssystems ausgeführt wird. 39

52 Quelltext 5.3: Aufräumen des Testsystems nach der Ausführung jedes Testfalls 1 p r i v a t e s t a t i c TestDatabaseSetup dbsetup = new TestDatabaseSetup ( ) ; 2 p u b l i c void teardown ( ) throws DatabaseSetupException { 4 dbsetup. c l e a r A l l T a b l e s ( ) ; 5 } Durch den vorgestellten Mechanismus können Seiteneekte zwischen einzelnen Testfällen ausgeschlossen werden. Zusätzlich gibt es keine Probleme, einen Testfall mehrfach hintereinander auszuführen. Dies ist ein groÿer Vorteil für die automatisierte Ausführung der erzeugten Tests, da kein zusätzlicher Aufwand betrieben werden muss, um das zu testende System in einem bestimmten Zustand zu halten Abhängigkeiten vom Domänenmodell Ein ähnliches Problem besteht darin, das Informationssystem für die einzelnen Tests in einen geeigneten Anfangszustand zu bringen. Zum Beispiel kann im Forensystem die Create-Methode der Thread-Entität nur erfolgreich getestet werden, wenn bereits entsprechende Forum- und User-Entitäten existieren, mit deren Hilfe die neue Thread-Entität erzeugt werden kann. Ein Beispiel für Abhängigkeiten zwischen Entitäten gibt der Testfall im Quelltext 5.1 auf Seite 36. Bevor die zu testende Fassadenmethode in Zeile 8 aufgerufen werden kann, wird in den Zeilen 4 bis 6 ein sogenanntes In-line Setup [Mes07] durchgeführt, das die für den Testfall nötigen Entitäten erzeugt und initialisiert. Die beschriebenen Abhängigkeiten sind direkt aus dem Domänenmodell des Forensystems ableitbar. Abbildung 5.1 auf Seite 36 zeigt den relevanten Ausschnitt des Domänenmodells des Forensystems. Um eine Instanz der Thread- Entität erzeugen zu können, muss die Kompositionsbeziehung zwischen Forum und Thread beachtet werden. Eine Thread-Entität kann also nie ohne Zuordnung zu einer entsprechenden Forum-Entität erzeugt werden. Auÿerdem wird im Quelltextbeispiel 5.1 des vorgestellten Testfalls eine User-Entität erzeugt, um die für die zu testende Fassadenmethode erforderliche Assoziation zwischen User und Thread aufbauen zu können. Die Verwaltung von Abhängigkeiten zwischen Entitäten ist einer der zentralen Punkte in der Konzeption der Testfall-Generierung im Gargoyle-Test-Generator. Die dazu benötigten Informationen sind im Entity-Modell der Gargoyle-Anwendung verfügbar. 40

53 Trennung von Testmethoden und Testfällen Um Code-Duplikate zu vermeiden und die generierten Testfälle auf einfache Weise wiederverwenden zu können, wurden die Testmethoden zweistug aufgebaut: Die einen Testfall beschreibende Testmethode enthält nur die Eingabedaten und nicht die Testfallschritte selbst. Diese sind in einer weiteren Methode implementiert, deren Schnittstelle genau die Testeingabeparameter enthält. Somit lassen sich auf einfache Weise mehrere Instanzen eines Tests mit verschiedenen Eingaben erstellen. Dies ist auÿerdem hilfreich, wenn der Ablauf eines Tests im Nachhinein angepasst werden muss. Das Quelltextbeispiel 5.4 demonstriert die Trennung anhand der Testmethode für die Erzeugung einer neuen Thread-Entität. Während die annotierten und vom JUnit-Rahmenwerk als eigenständige Testfälle ausgeführten Methoden in den Zeilen 1 und 5 zwei verschiedene Eingabeinstanzen für den Test beschreiben, ist der Testablauf in der Methode in Zeile 9 gekapselt. Durch das Hinzufügen einer weiteren annotierten Methode, die neue Eingabedaten deniert und anschlieÿend die gemeinsam genutzte Testmethode aufruft, kann ohne groÿe Aufwände ein neuer Testfall hinzugefügt werden. Quelltext 5.4: Trennung zwischen Testfällen und Testmethode p u b l i c void testcreatenewthreadforforum1 ( ) { 2 testcreatenewthreadforforum ( " title1 ", " user1 ", 1, " testtitle ", f a l s e ) ; 3 } 4 p u b l i c void testcreatenewthreadforforum2 ( ) { 6 testcreatenewthreadforforum ( " title2 ", " user2 ", 2, " testtitle 2", t r u e ) ; 7 } 8 9 p u b l i c void testcreatenewthreadforforum ( S t r i n g forumtitle, 10 S t r i n g username, i n t threadid, S t r i n g t i t l e, boolean l o c k e d ) { 11 / Implementierung des Tests / 12 } Im Kontext des Testens beschreibt diese Struktur eine Äquivalenzklasse mit verschiedenen Repräsentanten. Die gemeinsam genutzte Testmethode beschreibt genau einen erwarteten Programmablauf, also die Äquivalenzklasse. Die für die Äquivalenzklasse geeigneten Repräsentanten bilden die Testfälle, die alle die gemeinsame Methode mit dem Testablauf nutzen. Mit entsprechend ausgewählten Repräsentanten können auf diese Weise zum Beispiel Grenzwerttests durchgeführt werden Verarbeitung von Ausnahmen Bei Komponenten- und Integrationstests birgt die Prüfung der Ausnahmebehandlung (exception handling) von Methoden zusätzliche Herausforderungen. Um entsprechend ausgelöste Ausnahmen zu testen, bietet JUnit das Konzept der erwarteten Ausnahme (expected exception). Damit kann ein Testfall zusätzlich mit einer Information annotiert werden, dass die Auslösung einer bestimmten 41

54 Ausnahme erwartet wird (siehe Zeile 1 in Quelltext 5.5). Im Aufruf der den Test implementierenden Methode in Zeile 3 ist der Parameter für den Titel der im Test zu verwendenden Forum-Entität gleich null. Da es sich bei diesem Parameter um einen Primärschlüssel für die Forum-Entität handelt, ist der Wert null nicht zulässig. Dies führt zur Auslösung der Ausnahme NotNullableException. Quelltext 5.5: Testen von erwarteter Auslösung von Ausnahmen (1) ( expected=notnullableexception. c l a s s ) 2 p u b l i c void testcreatenewthreadforforumwithnullparent ( ) { 3 testcreatenewthreadforforum ( n u l l, " user1 ", 1, " testtitle ", f a l s e ) ; 4 } 5 6 p u b l i c void testcreatenewthreadforforum ( S t r i n g forumtitle, 7 S t r i n g username, i n t threadid, S t r i n g t i t l e, boolean l o c k e d ) { 8 / Implementierung des Tests / 9 } Diese Art der Ausnahmeprüfung kann zu unerwarteten Testergebnissen führen. Es reicht aus, dass irgendeiner der Methodenaufrufe des Tests die erwartete Ausnahme auslöst. Der Testfall könnte also als erfolgreich gewertet werden, auch wenn ein nicht erwarteter Testverlauf eintritt. Deshalb wurde eine andere Implementierung für die Ausnahmeprüfung gewählt, die in Quelltext 5.6 abgebildet ist. Durch den Try-Catch-Block in den Zeilen 7 und 17 bis 19 wird sichergestellt, dass eine ausgelöste Ausnahme an einer unvorhergesehenen Stelle im Testablauf als fehlgeschlagener Test gewertet wird. Dagegen erfolgt die Auswertung des zu testenden Methodenaufrufs aus Zeile 10 über den Try-Catch-Block in den Zeilen 9 bis 16. Nur das Auslösen einer NotNullableException an dieser Stelle führt zu einem erfolgreichen Testergebnis. Wird keine Ausnahme oder eine Ausnahme in einer anderen Quelltextzeile ausgelöst, schlägt der Test fehl. Diese Art der Implementierung ist somit robuster als der vorherige Lösungsansatz. Quelltext 5.6: Testen von erwarteter Auslösung von Ausnahmen (2) p u b l i c void testcreatenewthreadforforumwithnullparent ( ) { 2 testcreatenewthreadforforum ( n u l l, " user1 ", 1, " testtitle ", f a l s e ) ; 3 } 4 5 p u b l i c void testcreatenewthreadforforum ( S t r i n g forumtitle, 6 S t r i n g username, i n t threadid, S t r i n g t i t l e, boolean l o c k e d ) { 7 t r y { 8 /... / 9 t r y { 10 forumassociationsfacade. createnewthreadforforum ( forumtitle, 11 username, threadid, t h r e a d T i t l e, threadlocked ) ; 12 Assert. a s s e r t T r u e ( f a l s e ) ; // e r w a r t e t e Ausnahme n i c h t a u s g e l ö s t! 13 } catch ( NotNullableException e ) { 14 / e r w a r t e t e Ausnahme wurde a u s g e l ö s t, T e s t v e r l a u f e r f o l g r e i c h / 15 Assert. a s s e r t T r u e ( t r u e ) ; 16 } 17 } catch ( Exception e ) { 18 Assert. a s s e r t T r u e ( f a l s e ) ; // n i c h t e r w a r t e t e Ausnahme 19 } 20 } 42

55 Abstraktion des zu testenden Systems Um die Beschreibung von Tests möglichst einfach und unabhängig vom zu testenden System zu realisieren, wurde beschlossen, erneut das Konzept der Anwendungsfassade (siehe 2.1.4) zu verwenden. Dabei wird die Anwendungsschicht durch eine zusätzliche Test-Fassade vor der Testschicht verborgen. Diese interagiert nur noch mit der Test-Fassade und ist somit vollständig von der Anwendungsschicht entkoppelt. Ohne diese Abstraktionsschicht würde die Testbeschreibung im modellgetriebenen Ansatz nicht plattformunabhängig möglich sein. Das zu entwickelnde Test-Modell müsste Referenzen auf die Meta-Modelle der zu testenden Anwendung speichern, was eine plattformunabhängige Beschreibung von Tests und die Wiederverwendung der Test-Generator-Komponenten ausschlieÿt. Die zu testenden Methoden werden über die Test-Fassade verfügbar gemacht und an die eigentliche Methode des zu testenden Systems durchgeleitet. Dabei enthält die Schnittstelle der Anwendungsfassade Browser EJB Entities Application Server Datenbank Test-Wrapper (HtmlUnit) Test-Servlet (JUnit) Test-Fassade Anwendungsfassade Komponente Controller DAO Entity Manager Kontrollfluss Abb. 5.4.: Fassade zur Abstraktion der Anwendungsschicht nur primitive Datentypen. Dies ermöglicht das Testen auch für web-basierte Systeme, da diese normalerweise keinen Zugri auf das Domänenmodell haben und nur mit primitiven Datentypen arbeiten. In Abbildung 5.4 ist eine um die Test-Fassade erweiterte Schichtenarchitektur des Test-Prototypen zu sehen. Zwischen Test-Servlet und Anwendungsfassade wurde eine zusätzliche Fassade eingefügt, die die Testschicht vom zu testenden System trennt. Zwischen Tests und der Anwendungsschicht bestehen somit keine direkten Abhängigkeiten mehr. Testschicht Gargoyle-Anwendung Klassikation von Testschritten Durch mehrmaliges Refaktorisieren (Refactoring [Fow99b]) der einzelnen Testfälle konnten Gemeinsamkeiten in der Testschrittfolge herausgearbeitet werden. In Kombination mit den zuvor beschriebenen Erweiterungen bezüglich der Schnittstellen der Testmethoden und der Abstraktion der Anwendungsschicht 43

56 über eine Test-Fassade konnte die folgende Klassikation für Testschritte in den Tests des Prototypen identiziert werden: 1. Deklaration von lokalen Variablen und Initialisierung durch Standardwerte 2. Initialisierung von lokalen Variablen durch Parameter der Testmethoden- Schnittstelle 3. Aufruf einer oder mehrerer Fassadenmethoden zur Bereitstellung der für den Testfall benötigten Daten im Informationssystem 4. Aufruf der zu testenden Fassadenmethode a) als normaler Aufruf einer Fassadenmethode b) als Aufruf einer Fassadenmethode mit Auslösung einer Ausnahme 5. Aufruf von Prüfmethoden zur Validierung des erwarteten Ergebnisses, ebenfalls über Aufrufe entsprechender Fassadenmethoden Diese Liste deniert gleichzeitig eine geeignete Abfolge der Testschritte. Testabläufe können so besser strukturiert werden, wodurch ihre Lesbarkeit erhöht wird. Auch vereinfacht die Klassizierung und Ordnung von Testschritten die Modellierung und Generierung von Testfällen in der zu entwickelnden modellgetriebenen Lösung. 44

57 6. Testmuster Inhalt 6.1 Testklassikation Testmuster Dieses Kapitel beschreibt die während der Prototypingphase entwickelten Testmuster. Es soll eine Übersicht über den Prozess der manuellen Testerstellung während der Prototyperstellung geben. Auÿerdem werden einzelne der entwickelten Testmuster durch Quelltextbeispiele beschrieben und die einzelnen Testschritte in das in Abschnitt vorgestellte Klassikationsschema eingeordnet. Der Gargoyle-Generator war während der Prototypingphase noch nicht voll funktionsfähig. Zum Zeitpunkt der Testmustererstellung war der Generator noch nicht in der Lage, Funktionen zur Verwaltung von Assoziationen (z. B. Assignund Unassign-Methoden) zu generieren. Ebenfalls war noch nicht geklärt, wie sich die generierten Anwendungen bei Löschoperationen von komponierten Entitäten verhalten sollen. Folglich konnten nur für einen Teil der Fassadenmethoden Tests entwickelt werden. Aus diesem Grund beschränkt sich dieses Kapitel auf eine Auswahl an Testmustern zu den Create-, Read-, Update- und Delete- Methoden. Die hier vorgestellten Testmuster waren ausreichend, um die Konzepte für die spätere Entwicklung des Gargoyle-Testgenerators zu evaluieren Testklassikation Zu Beginn der Prototypingphase wurden geeignete Testmuster für die Gargoyle-Anwendungsfassade evaluiert. Dabei konnten verschiedene Testklassen aus den Signaturen der Fassadenmethoden abgeleitet werden. Neben einem Positivtest, der die erfolgreiche Ausführung einer Methode zum Ziel hat, konnten auch Fehlertests anhand der potentiell ausgelösten Ausnahmen der Methoden konstruiert werden. Die zu testenden Fassadenmethoden wurden in die Methodenklassen Create, Read, Update, Delete und Get-All unterteilt. Die Bedeutung der ersten vier Methodentypen ist hinreichend bekannt. Bei Get-All-Methoden handelt es sich um Zugrismethoden für Top-Level-Elemente (siehe Abschnitt 2.5.2), die den Zugri auf alle Entitäten eines bestimmten Typs erlauben. Als erste Klasse von Fehlertests wurden die Duplication-Tests identiziert. Im Gargoyle-Kontext entspricht dieser Fall dem Auslösen einer Ausnahme des Typs 45

58 AlreadyInDBException. Die Ausnahme wird immer dann ausgelöst, wenn versucht wird, eine Entität mit identischem Primärschlüssel mehrfach zu erzeugen. Dieses Problem kann sowohl bei Create- als auch Update-Methoden auftreten. Not-Nullable-Tests prüfen, ob bei einem Methodenaufruf bestimmte Parameter leer oder null sein dürfen. Dies ist nicht für Parameter erlaubt, die Primärschlüssel, Fremdschlüssel oder Attribute repräsentieren, die im Gargoyle-EJB- Generatormodell explizit als not-nullable modelliert wurden. Not-Nullable-Tests können für alle Methodentypen auÿer den Get-All-Methoden angewendet werden. Die im Testfall von der EJB-Anwendungsfassade ausgelöste Ausnahme ist die NotNullableException. Die Klasse der Not-Found-Tests repräsentiert Fehlertests, die die Auslösung von Ausnahmen aufgrund fehlerhafter Primär- oder Fremdschlüssel prüfen. Diese Art von Tests sind wiederum auf alle Methodentypen auÿer den Get-All- Methoden anwendbar. Dabei können zum Beispiel Create-Methoden mit Fremdschlüsselparameterwerten aufgerufen werden, die auf ein nicht vorhandenes Vaterelement verweisen. Die Ausnahme, die von diesem Methodenaufruf ausgelöst wird, heiÿt NotFoundException. Tabelle 6.1 fasst die Methodentypen und die darauf anwendbaren Testmuster zusammen. Die hier vorgestellte Liste von Testtypen erhebt keinen Anspruch auf Vollständigkeit. Sie stellt eine Auswahl an Tests für die Gargoyle-Anwendungsfassade dar, die die Grundlage für die Entwicklung des modellgetriebenen Ansatzes zur automatischen Testgenerierung bildeten. Auch für die später hinzugefügten Fassadenmethoden zur Assoziationsverwaltung ergeben sich zusätzliche Möglichkeiten, neue Testmuster zu denieren und miteinander zu kombinieren. Methodentyp Positiv Duplication Not-Nullable Not-Found... Create... Read... Update... Delete... Get-All... Assign Unassign Abb. 6.1.: Anwendbarkeit von Testtypen auf Gargoyle-Anwendungsfassade 6.2. Testmuster In diesem Abschnitt werden die vorgestellten Testmuster durch eine Auswahl von Quelltextbeispielen präzisiert. Die Testschritte der einzelnen Beispiele werden anhand der in Abschnitt ausgearbeiteten Klassikation unterteilt. Dies 46

59 ist durch Kommentarzeilen in den Quelltextbeispielen kenntlich gemacht. Dabei wird zwischen test inputs, test setup, Method Under Test, test outputs und assertions (Prüfungen) unterschieden. Der Punkt (2) der Testschrittklassizierung aus Abschnitt ndet bei den hier vorgestellten Testmustern noch keine Anwendung, da das Konzept der wiederverwendbaren Testmethoden zum Zeitpunkt der Prototyperstellung noch nicht implementiert wurde Positivtests Das Quelltextbeispiel 6.1 zeigt einen Create-Test für die Top-Level-Entität Forum. Der Testfall besteht aus drei grundlegenden Schritten: dem Denieren der Eingabedaten (Zeile 4), dem Ausführen der zu testenden Methode (Zeile 6) und dem Laden der erzeugten Entität mit anschlieÿender Überprüfung der zum Anlegen verwendeten Attribute (Zeilen 8 bis 10). Quelltext 6.1: Positivtest für Create-Methode 2 p u b l i c void testcreateforum ( ) { 3 // t e s t i n p u t s 4 S t r i n g forumtitle = " defaultforum " ; 5 // Method Under Test 6 forumfacade. createforum ( forumtitle ) ; 7 // a s s e r t i o n s 8 Forum forum = forumfacade. getforumbytitle ( forumtitle ) ; 9 Assert. a s s e r t N o t N u l l ( forum ) ; 10 Assert. a s s e r t E q u a l s ( forumtitle, forum. g e t T i t l e ( ) ) ; 11 } Der Testfall im Quelltext 6.2 ist dagegen komplexer, da für die Ausführung der Testmethode (Zeile 12) bereits eine Forum- und eine Thread-Entität vorhanden sein muss. Diese werden im Test-Setup erzeugt (Zeilen 9 und 10). Quelltext 6.2: Positivtest für Getter-Methode 2 p u b l i c void testgetthreadbytitleandthreadid ( ) { 3 // t e s t i n p u t s 4 S t r i n g t i t l e = " defaultforum " ; 5 i n t threadid = 1 ; 6 S t r i n g t h r e a d T i t l e = " defaultthreadtitle " ; 7 boolean l o c k e d = f a l s e ; 8 // t e s t setup 9 forumfacade. createforum ( t i t l e ) ; 10 forumfacade. createthread ( threadid, t i t l e, t h r e a d T i t l e, l o c k e d ) ; 11 // Method Under Test 12 Thread thread = 13 forumfacade. getthreadbythreadidandtitle ( threadid, t i t l e ) ; 14 // a s s e r t i o n s 15 Assert. a s s e r t N o t N u l l ( thread ) ; 16 Assert. a s s e r t E q u a l s ( t i t l e, thread. g e t T i t l e ( ) ) ; 17 Assert. a s s e r t E q u a l s ( threadid, thread. getthreadid ( ) ) ; 18 Assert. a s s e r t E q u a l s ( t h r e a d T i t l e, thread. getthreadtitle ( ) ) ; 19 Assert. a s s e r t E q u a l s ( locked, thread. getlocked ( ) ) ; 20 } 47

60 Weitere Typen von Positivtests Aus Gründen der Vollständigkeit werden an dieser Stelle auch Beispiele für Positivtests der anderen Methodentypen präsentiert. Für Update-Tests wird das korrekte Setzen von neuen Attributwerten geprüft (siehe Quelltext 6.3). Dazu wird eine Entität erzeugt und anschlieÿend deren Werte geändert. Dann wird überprüft, ob die neuen Attributwerte erfolgreich im Informationssystem gespeichert wurden. Ein Sonderfall besteht bei Primärund Fremdschlüsselattributen: Für diese kann abschlieÿend ein Zugri auf die alte Entität erfolgen, um zu testen ob diese nicht mehr in der Datenschicht vorhanden ist. Dazu wird der Aufruf der Zugrismethode in einem Try-Catch- Block gekapselt, um die erfolgreiche Auslösung der erwarteten Ausnahme zu prüfen. Quelltext 6.3: Positivtest für Update-Methode 2 p u b l i c void testupdateforum ( ) { 3 // t e s t i n p u t s 4 S t r i n g t i t l e 1 = " defaultforum " ; 5 S t r i n g t i t l e 2 = " newforum " ; 6 7 // t e s t setup 8 forumfacade. createforum ( t i t l e 1 ) ; 9 10 // Method Under Test 11 forumfacade. updateforum ( t i t l e 1, t i t l e 2 ) ; // a s s e r t i o n s 14 Forum forum = 15 forumfacade. getforumbytitle ( t i t l e 2 ) ; 16 Assert. a s s e r t N o t N u l l ( forum ) ; 17 Assert. a s s e r t E q u a l s ( t i t l e 2, forum. g e t T i t l e ( ) ) ; 18 // a s s e r t that old Forum i s gone 19 t r y { 20 forumfacade. getforumbytitle ( t i t l e 1 ) ; 21 // f a i l! 22 Assert. f a i l ( ) ; 23 } catch ( NotFoundException e ) { 24 // s u c c e s s! 25 } 26 } Delete-Tests erzeugen eine Entität, um diese anschlieÿend wieder zu löschen. Zur Prüfung der erfolgreichen Löschung wird die Entität erneut zugegrien und die Auslösung einer Ausnahme erwartet. Der entsprechende Testfall für eine Thread-Entität ist im Quelltext 6.4 abgebildet. 48

61 Quelltext 6.4: Positivtest für Delete-Methode 2 p u b l i c void testdeletethread ( ) { 3 // t e s t i n p u t s 4 S t r i n g t i t l e = " defaultforum " ; 5 i n t threadid = 1 ; 6 S t r i n g t h r e a d T i t l e = " defaultthreadtitle " ; 7 boolean l o c k e d = f a l s e ; 8 // t e s t setup 9 forumfacade. createforum ( t i t l e ) ; 10 forumfacade. createthread ( threadid, t i t l e, t h r e a d T i t l e, l o c k e d ) ; 11 // Method Under Test 12 forumfacade. deletethread ( threadid, t i t l e ) ; 13 // a s s e r t i o n s 14 t r y { 15 forumfacade. getthreadbythreadidandtitle ( threadid, t i t l e ) ; 16 // f a i l! 17 Assert. f a i l ( ) ; 18 } catch { 19 // s u c c e s s! 20 } 21 } Get-All-Methoden dienen zum Zugri auf alle Entitäten eines Typs. Zum testen dieser Funktionalität wird eine Menge von Entitäten erzeugt und dann über die GetAll-Methode geladen. Anschlieÿend kann sowohl die Mächtigkeit der zurückgelieferten Menge von Entitäten, als auch deren Inhalt geprüft werden. Quelltext 6.5 zeigt die entsprechenden Erzeugungs-, Zugris- und Prüfschritte. Quelltext 6.5: Positivtest für GetAll-Methode 2 p u b l i c void testgetallforum ( ) { 3 // t e s t i n p u t s 4 S t r i n g t i t l e 1 = " forum1 " ; 5 S t r i n g t i t l e 2 = " forum2 " ; 6 // t e s t setup 7 forumfacade. createforum ( t i t l e 1 ) ; 8 forumfacade. createforum ( t i t l e 2 ) ; 9 // Method Under Test 10 Set<Forum> forums = forumfacade. getallforum ( ) ; // a s s e r t i o n s 13 Assert. a s s e r t N o t N u l l ( forums ) ; 14 Assert. a s s e r t E q u a l s ( forums. s i z e ( ), 2) ; Forum forum1 = forumfacade. getforumbytitle ( t i t l e 1 ) ; 17 Assert. a s s e r t N o t N u l l ( forum1 ) ; 18 Forum forum2 = forumfacade. getforumbytitle ( t i t l e 2 ) ; 19 Assert. a s s e r t N o t N u l l ( forum2 ) ; Assert. a s s e r t T r u e ( forums. c o n t a i n s ( forum1 ) ) ; 22 Assert. a s s e r t T r u e ( forums. c o n t a i n s ( forum2 ) ) ; 23 } 49

62 Duplikats-Tests Quelltext 6.6 zeigt einen Duplikats-Test für die Create-Methode der Entität Forum (Zeile 2). Charakteristisch für diese Testklasse ist, dass die mehrfach zu erzeugende Entität einmal im Test-Setup (Zeile 6) und einmal in der Method Under Test (Zeile 8) generiert wird. Duplication-Tests enthalten keine Testauswertungsschritte bzw. Prüfschritte, da eine Auslösung einer Ausnahme für die zu testende Methode erwartet wird. Bei Update-Methoden ist die Testausführung ähnlich. Eine Beispielmethode ist in Zeile 12 im Quelltext 6.6 abgebildet. Anstatt eine Entität doppelt zu erzeugen, müssen im Test-Setup zwei Entitäten des gleichen Typs mit unterschiedlichen Primärschlüsseln erzeugt werden (Zeilen 17 und 18). Anschlieÿend wird versucht, den Primärschlüssel der zweiten Entität auf den Primärschlüssel der ersten Entität zu aktualisieren (Zeile 20). Quelltext 6.6: Duplication-Tests ( expected=alreadyindbexception. c l a s s ) 2 p u b l i c void testcreateforum_alreadyindbexception ( ) { 3 // t e s t i n p u t s 4 S t r i n g forumtitle = " forumtitle " ; 5 // t e s t setup 6 forumfacade. createforum ( forumtitle ) ; 7 // Method Under Test 8 forumfacade. createforum ( forumtitle ) ; 9 } 10 ( expected=alreadyindbexception. c l a s s ) 12 p u b l i c void testupdateforum_alreadyindbexception ( ) { 13 // t e s t i n p u t s 14 S t r i n g t i t l e 1 = " defaultforum1 " ; 15 S t r i n g t i t l e 2 = " defaultforum2 " ; 16 // t e s t setup 17 forumfacade. createforum ( t i t l e 1 ) ; 18 forumfacade. createforum ( t i t l e 2 ) ; 19 // Method Under Test 20 forumfacade. updateforum ( t i t l e 2, t i t l e 1 ) ; 21 } 50

63 Not-Nullable-Tests Im Quelltext 6.7 sind Beispiele für Not-Null-Tests zu sehen. Der erste Teil der Abbildung demonstriert zwei Not-Null-Tests für Primärschlüssel, unter Nutzung einer Null-Zeichenkette (Zeile 2) und einer leeren Zeichenkette (Zeile 10). Der untere Teil des Quelltextes zeigt Not-Null-Tests für Wertattribute (Zeilen 18 und 34). Für alle vier abgebildeten Testfälle wird eine Ausnahme des Typs NotNullableException erwartet. Quelltext 6.7: Not-Null-Tests für Primärschlüssel und Wertattribute ( expected=notnullableexception. c l a s s ) 2 p u b l i c void testcreateforum_ NotNullableException_ Title1 ( ) { 3 // t e s t i n p u t s 4 S t r i n g forumtitle = n u l l ; 5 // Method Under Test 6 forumfacade. createforum ( forumtitle ) ; 7 } 8 ( expected=notnullableexception. c l a s s ) 10 p u b l i c void testcreateforum_ NotNullableException_ Title2 ( ) { 11 // t e s t i n p u t s 12 S t r i n g forumtitle = "" ; 13 // Method Under Test 14 forumfacade. createforum ( forumtitle ) ; 15 } 16 ( expected=notnullableexception. c l a s s ) 18 p u b l i c void testupdatethread_notnullableexception_forumtitle ( ) { 19 // t e s t i n p u t s 20 S t r i n g t i t l e = " defaultforum " ; 21 i n t threadid = 1 ; 22 S t r i n g t h r e a d T i t l e 1 = " defaultthreadtitle " ; 23 S t r i n g t h r e a d T i t l e 2 = n u l l ; 24 boolean l o c k e d = f a l s e ; 25 // t e s t setup 26 forumfacade. createforum ( t i t l e ) ; 27 forumfacade. createthread ( threadid, t i t l e, t h r e a d T i t l e, l o c k e d ) ; 28 // Method Under Test 29 forumfacade. updatethread ( threadid, threadid, t i t l e, t h r e a d T i t l e 2, 30 l o c k e d ) ; 31 } 32 ( expected=notnullableexception. c l a s s ) 34 p u b l i c void testcreatethread_ NotNullableException_ ThreadTitle ( ) { 35 // t e s t i n p u t s 36 S t r i n g t i t l e = " defaultforum " ; 37 i n t threadid = 1 ; 38 S t r i n g t h r e a d T i t l e = "" ; 39 boolean l o c k e d = f a l s e ; 40 // t e s t setup 41 forumfacade. createforum ( t i t l e ) ; 42 // Method Under Test 43 forumfacade. createthread ( threadid, t i t l e, t h r e a d T i t l e, l o c k e d ) ; 44 } 51

64 Not-Found-Tests Um Fehler bei der Auösung von Entitäten anhand ihrer Primär- und Fremdschlüssel zu testen, werden Not-Found-Tests verwendet. Diese prüfen das Auslösen einer Ausnahme vom Typ NotFoundException. Quelltext 6.8 zeigt Beispiele für Not-Found-Tests einer Getter- und einer Delete-Methode. Quelltext 6.8: Not-Found-Tests für Primär- und Fremdschlüssel ( expected=notfoundexception. c l a s s ) 2 p u b l i c void testgetforumbytitle_notfoundexception ( ) { 3 // t e s t i n p u t s 4 S t r i n g t i t l e = " unknowntitle " ; 5 // Method Under Test 6 Forum forum = forumfacade. getforumbytitle ( t i t l e ) ; 7 } 8 ( expected=notfoundexception. c l a s s ) 10 p u b l i c void testdeleteforum_notfoundexception_threadid ( ) { 11 // t e s t i n p u t s 12 S t r i n g t i t l e 1 = " defaultforum " ; 13 S t r i n g t i t l e 2 = " unknownforum " ; 14 i n t threadid = 1 ; 15 S t r i n g t h r e a d T i t l e = " defaultthreadtitle " ; 16 boolean l o c k e d = f a l s e ; 17 // t e s t setup 18 forumfacade. createforum ( t i t l e 1 ) ; 19 forumfacade. createthread ( threadid, t i t l e 1, t h r e a d T i t l e, l o c ked ) ; 20 // Method Under Test 21 forumfacade. deletethread ( threadid, t i t l e 2 ) ; 22 } 52

65 7. Verwandte Arbeiten Inhalt 7.1 Modellgetriebene Testgenerierung aus Sequenzdiagrammen Modellbasierte Testfallbeschreibung auf Basis von Use Cases Code- und Testgenerierung mit Spring Roo Für die modellbasierte und modellgetriebene Testentwicklung existiert eine Vielzahl von Ansätzen. An dieser Stelle werden drei verschiedene Konzepte und Projekte vorgestellt, die als Vorbild für einzelne Komponenten des Gargoyle- Test-Generators dienen. 1. Der erste vorgestellte Ansatz zur modellgetriebenen Generierung von Tests stammt von einer Forschergruppe der Universität Queensland, Australien [JSW07]. Sie verfolgen einen Ansatz, der aus Sequenzdiagrammen Testfälle ableitet. Die vorgestellte Methode setzt dabei auf Technologien aus dem Eclipse-Umfeld und bietet eine plattformunabhängige Beschreibung für Testfälle und Codegeneratoren für verschiedene Unit-Test-Rahmenwerke. 2. Die zweite vorgestellte Arbeit befasst sich mit der Beschreibung von Testfällen auf Basis textuell beschriebener Anwendungsfälle und deren modellbasierter Darstellung. Der Ansatz wurde von Kamil Bora Kiliclar im Zuge einer Diplomarbeit entwickelt [Kil10] und bildet die Vorlage für Teile des in Kapitel 9 vorgestellten Test-Modells. 3. An dritter Stelle wird Spring Roo vorgestellt, eine Umgebung für Rapid Application Development (RAD) mit einer Vielzahl an Funktionen für die Generierung von Java-Anwendungen [LM11]. Sie zeichnet sich besonders durch ihren hohen Automatisierungsgrad bei der Codegenerierung und der Integration von Anwendungen in ihre Laufzeitumgebung aus. Die Konzepte und Lösungen der vorgestellten Methoden werden mit dem Gargoyle-Test-Generator verglichen. Dabei werden positive und negative Aspekte herausgearbeitet und deren Einuss auf die Entwicklung des Gargoyle-Test- Generators herausgestellt. 53

66 7.1. Modellgetriebene Testgenerierung aus Sequenzdiagrammen In einer Studie von Mussa et al. wurde auf verschiedene Methoden zum modellgetriebenen Testen eingegangen und ein Überblick über heutige Verfahren zur Testgenerierung gegeben [MOSHL09]. Die meisten vorgestellten Ansätze basieren auf der Erzeugung von Tests aus Sequenzdiagrammen, Zustandsdiagrammen, Use Cases oder Aktivitätsdiagrammen, die das Verhalten von Anwendungen beschreiben. An dieser Stelle wird eine Methode vorgestellt, deren Konzepte und verwendete Technologien viele Gemeinsamkeiten mit dem in dieser Arbeit entwickelten Ansatz haben. Javed, Strooper und Watson von der Universität Queensland haben eine modellgetriebene Methode zur Generierung von Tests entwickelt, die auf Sequenzdiagrammen basiert [JSW07]. Die vorgestellte Methode ist in Abbildung 7.1 zu sehen. Die Testfälle werden bei dieser Methode als Sequenz von Methodenaufrufen in einem plattformunabhängigen Modell dargestellt. Anschlieÿend werden die Tests in ein ebenfalls plattformunabhängiges xunit-modell transformiert, das die allgemeine Struktur von Unit-Tests nachbildet. Aus diesem können Testfälle für verschiedene Unit-Test-Rahmenwerke generiert werden, zum Beispiel JUnit für Java-Umgebungen oder SUnit für Smalltalk-Umgebungen [Bec98]. Zur Generierung der Testfälle werden zusätzlich Testdaten und Code-Templates verwendet. UML Model (Sequence Diagram) Tefkat xunit Model Platform Independent Model Platform Specific Model Modell/Quelltext JUnit Test Case MOFScript SUnit Test Case Modelltransformation Test Data Templates Abb. 7.1.: Modellgetriebene Testgenerierung nach Javed et al. [JSW07] Die Forscher setzen auf Modelltransformations- und Codegeneratortechnologien, die auf Eclipse und dem Eclipse Modeling Framework (EMF) basieren. Die Modelltransformation zwischen den Sequenzdiagrammen und dem xunit-modell wird über Tefkat realisiert. Tefkat ist eine Modelltransformationsumgebung, die eine deklarative Sprache für Transformationsregeln zur Beschreibung von Abbildungen zwischen Modellen bereitstellt [Sou08]. Für die Codegenerierung der Tests wird MOFScript verwendet, eine regelbasierte Sprache für Model-To- Text-Transformationen [Ecl09]. 54

67 Abgrenzung Die vorgestellte Methode unterscheidet sich bei der Testgenerierung von dem in dieser Diplomarbeit behandelten Ansatz, bei den verwendeten Technologien und der Codegenerierung bestehen wiederum Gemeinsamkeiten. Testgenerierung Die Methode von Javed et al. und die anderen in der Studie von Mussa et al. vorgestellten Ansätze zur Testgenerierung unterscheiden sich stark von der in dieser Diplomarbeit entwickelten Methode. Die in der Studie betrachteten Lösungen leiten ihre Testfälle aus Modellen ab, die das Verhalten einer Anwendung bzw. Komponente beschreiben, zum Beispiel aus Sequenz- oder Aktivitätsdiagrammen. Im Falle des Gargoyle-Generators sind diese Informationen nicht vorhanden, sondern es liegt nur ein statisches Domänenmodell der Anwendung vor. Aus diesen strukturellen Informationen und dem Wissen über die Architektur sowie der Semantik der Fassadenmethoden der generierten Anwendung werden Testfälle über Heuristiken abgeleitet. Eine vorherige Modellierung von zu testenden Anwendungsfällen ist daher nicht nötig. Die im Falle des Gargoyle-Test-Generators durchgeführte Ableitung von Testbzw. Anwendungsfällen aus statischen, strukturellen Modellinformationen ist im Allgemeinen nicht möglich. Dies kann nur aufgrund der Tatsache durchgeführt werden, dass die Anwendungsdomäne auf Informationssysteme eingeschränkt ist. Die mit den CRUD-Funktionen zusammenhängenden Anwendungsfälle sind dabei intuitiv ableitbar. Allgemeine Ansätze zur Testfallerzeugung können diese Annahmen nicht tätigen, eine Generierung von Testfällen anhand der statischen Struktur eines Systems auÿerhalb der Domäne der Informationssysteme ist daher nicht sinnvoll. Eclipse-Plattform Sowohl der Ansatz von Javed et al. als auch die Gargoyle-Test-Generator basieren auf der Eclipse-Plattform. Diese hat einen hohen Verbreitungsgrad und hat sich bei der Entwicklung von unzähligen Anwendungen bewährt. Mit Problemen bei der Unterstützung der verwendeten Technologien ist in näherer Zukunft nicht zu rechnen. Codegeneratorkomponenten Die vorgestellte Methode erlaubt durch das generische xunit-meta-modell, dass Tests unabhängig von der verwendeten Implementierungsplattform beschrieben werden können. Die Festlegung auf das zu verwendende Unit-Test-Rahmenwerk 55

68 und die dazugehörige Programmiersprache geschieht erst bei der Codegenerierung, also zum spätmöglichsten Zeitpunkt. Die Autoren heben hervor, dass die Codegeneratoren für die verschiedenen Programmiersprachen groÿe strukturelle Gemeinsamkeiten haben. Beim Vergleich der Codegeneratoren für JUnit und SUnit konnte für die meisten Generatorfunktionen eine Übereinstimmung von über 80 Prozent festgestellt werden [JSW07]. In vielen Fällen mussten nur die sprachspezischen Textbausteine ausgetauscht werden. Sowohl das xunit-meta- Modell als auch die Codegeneratoren sind für eine Vielzahl anderer Entwicklungsprojekte und Anwendungen wiederverwendbar. Auch das Test-Modell des Gargoyle-Test-Generators orientiert sich an der allgemeinen Struktur von Unit-Test-Rahmenwerken. Implementierungsspezische Details werden abstrahiert, um eine generische Beschreibung von Tests zu erreichen. Bei der Codegenerierung wurde mit der Xpand-Templatesprache eine andere Technologie gewählt, die bei Bedarf eine ähnlich hohe Wiederverwendung der Generatorskripte erlaubt. Dadurch ist auch beim Gargoyle-Test-Generator die Generierung von Tests in verschiedenen Programmiersprachen möglich. Es wurde aber nur ein Codegenerator für Java-basierte Tests implementiert. Für weitere Programmiersprachen müssen zusätzliche Codegeneratorkomponenten implementiert werden, die die Generierung der entsprechenden Sprachsyntax übernehmen Modellbasierte Testfallbeschreibung auf Basis von Use Cases Die Arbeit von Kiliclar befasst sich mit der modellbasierten Erstellung von Tests aus textuell beschriebenen Anwendungsfällen (narrative Use Cases [HLAW09]). Kiliclar beschreibt dabei einen Prozess zur schrittweisen Erstellung von Testfallspezikationen [Kil10]. Der beschriebene Prozess dient unter anderem zur Erstellung und Klassikation von Testdaten, zur Verwaltung von Testszenarien und zur modellbasierten Darstellung von Testfällen. Im Zuge dieses Prozesses nimmt er eine Klassizierung einzelner Testschritte im Hinblick auf ihre Rolle im Anwendungsfall vor. Für die hier vorliegende Diplomarbeit ist besonders Kiliclars Darstellung von Testfällen relevant. Dabei bildet er, wie auch die bereits vorgestellte Arbeit von Javed et al., die grundlegende Struktur von Unit-Test-Rahmenwerken nach. Abbildung 7.2 zeigt einen Ausschnitt des TestSpecicationModels. Besonders hervorzuheben ist die hierarchische Organisation von Tests in Testgruppen (Test- Group), Testsuiten (TestSuite) und Testfällen (TestCase). Auÿerdem werden spezielle Testschritte (TestStep) klassiziert. Im vorliegenden Fall können Testschritte mit Eingabe- und Ausgabesemantik modelliert werden. 56

69 TestSpecification product : String description : String date : EDate SetUp TestSpecElement name : String CleanUp TestGroup TestSuite TestCase mainflow : Boolean TestStep name : String activity : String RelatedUseCase usecase : NarrativeDescription TestStepInput input : String TestStepOutput output : String Abb. 7.2.: TestSpecicationModel nach Kiliclar (Auszug) [Kil10] Abgrenzung Teile des von Kiliclar entwickelten Modells zur Testspezikation wurden bei der Entwicklung des Test-Modells des Gargoyle-Test-Generators wiederverwendet. Das Konzept der Testschrittklassizierung wird in abgewandelter Form genutzt. Die für den Test-Generator vorgenommene Klassikation wurde bereits in Abschnitt beschrieben. Im Bereich der Verwaltung von Testfällen, Testumgebungen und bei der Ableitung von geeigneten Testdaten birgt Kiliclars Ansatz klare Vorteile. Diese Aufgabe wird bei der hier vorgestellten modellgetriebenen Lösung nur ansatzweise unterstützt. Hauptziel der vorliegenden Arbeit ist die Demonstration der Machbarkeit einer durchgängigen Methode zur Testgenerierung. Funktionen zur Verwaltung von Testfällen, Testumgebungen und dazugehöriger Testdaten sind nur so weit implementiert, wie dies für die durchgängige automatische Generierung notwendig ist. 57

70 7.3. Code- und Testgenerierung mit Spring Roo Spring Roo [Spr12b] ist ein Rapid Application Development Tool für Java. Es bietet umfangreiche Funktionen zur Codegenerierung für eine Vielzahl von Java- Technologien, zum Beispiel aus dem Umfeld des Spring Frameworks [Spr12a]. Über Kommandozeilenbefehle kann auf einfache Weise ein Domänenmodell für eine Anwendung speziziert werden. Dazu müssen nur die einzelnen Entitäten, deren Attribute und Assoziationen deniert werden. Für diese Anwendung können verschiedene Generatoren verwendet werden, die zum Beispiel die folgenden Funktionen realisieren: Bereitstellung von Standard-Zugrismethoden für die Entitäten sowie deren Attribute und Assoziationen Generierung von Eclipse-Plugins für die Anwendung Persistierung des Domänenmodells, z. B. über die Java Persistence API Generierung von web-basierten Oberächen für das Domänenmodell, z. B. über Java Server Pages Generierung von Containern für Application Server und automatisches Deployment Generierung von JUnit-basierten Testfällen für das Domänenmodell Generierung von Selenium-Tests für die web-basierten Oberächen [Sel12] Mit Spring Roo können in kurzer Zeit Prototypen für web-basierte Informationssysteme und dazugehörige Tests generiert werden. Dabei unterstützt der Roo- Interpreter Round-Trip-Engineering und reagiert selbständig auf Anpassungen des Quellcodes. Auÿerdem wird manuell implementierter Quellcode vom generierten Quellcode getrennt. Spring Roo operiert dabei ausschlieÿlich auf dem Quelltext, es werden keine abstrakteren Modelle verwendet Abgrenzung Die Generatorkomponenten von Spring Roo erlauben die Erstellung von Systemen, die ähnliche Funktionen bereitstellen wie Gargoyle-basierte Anwendungen. Allerdings wird nur ein grundlegendes Domänenmodell erzeugt und keine Schichtenarchitektur mit Fassaden-, Controller- und DAO-Komponenten. Die mit Spring Roo generierten JUnit-Tests prüfen die Zugrismethoden (zum Beispiel Create-, Read- und Delete-Methoden) für die Persistenzschicht. Diese können als Installationstests verwendet werden, um die grundlegende Funktionalität einer Anwendung zu validieren. Dabei werden allerdings keine Asso- 58

71 ziationen bzw. Kompositionen beachtet, sondern jede Entität einzeln getestet. Die Testgenerierung basiert allein auf Heuristiken, die auf den Quellcode der Domänenklassen angewendet werden. Umfangreichere Testfälle, die Anwendungsfälle darstellen, können nicht generiert werden. Der in dieser Arbeit beschriebene Ansatz besitzt weitaus umfangreichere Funktionen zur Testerzeugung und -generierung als Spring Roo. Dessen Codegeneratorkomponenten sind allerdings ausgereifter und unterstützen eine Vielzahl unterschiedlicher Funktionen, zum Beispiel das Erzeugen von Eclipse-Projekten für den generierten Code oder das Erstellen und Deployment von Anwendungen in Application Servern. 59

72

73 Teil III. Konzeption und Implementierung 61

74

75 8. Konzeption und Implementierung Inhalt 8.1 Grobkonzeption Entwicklungsumgebung Überblick In der Entwurfs- und Implementierungsphase galt es, die Ergebnisse der Prototypingphase auf eine modellgetriebene Methode abzubilden. Dabei konnten drei Hauptanforderungen identiziert werden: 1. Modellierung von Testfällen 2. Abstraktion des zu testenden Systems 3. Modellgetriebene, automatische Erstellung von Testfällen Die Lösung dieser drei Aufgaben und die damit zusammenhängenden Konzepte, Meta-Modelle, Transformationen, Modellinstanzen und Codegeneratoren werden in den nächsten Kapiteln näher beschrieben. Dazu wird zunächst innerhalb dieser Einführung ein grober Überblick über den entwickelten Ansatz gegeben, der im Laufe der folgenden Kapitel schrittweise verfeinert wird und somit die Einordnung der vorgestellten Komponenten in den Gesamtkontext erleichtert. Abschlieÿend werden die einzelnen Bereiche kombiniert und die Gesamtarchitektur des entwickelten Prototypen des Gargoyle-Test-Generators sowie die dadurch implementierte modellgetriebene Methode vorgestellt Grobkonzeption Ausgehend von der geplanten Schichtenarchitektur aus Abbildung 5.4 auf Seite 43 wurde ein modellgetriebener Ansatz zur Generierung der einzelnen Komponenten der Gargoyle-Test-Generators entwickelt. Dieser ist schematisch in Abbildung 8.1 dargestellt. Der linke Teil der Abbildung repräsentiert das zu testende System, die Modelle und die daraus generierten Quelltextartefakte des bestehenden Gargoyle-Generators. Detaillierte Informationen zum Gargoyle-Generator bietet der Abschnitt im Teil I dieser Arbeit. 63

76 Gargoyle (a) Test- Fassaden (b) Test- Generierung (c) Test- Modellierung «model» Gargoyle Modelle «model» Test-Fassade(n) «model» Test-Modell «code» Domäne Test-Muster «code» Gargoyle- Komponenten «code» Test-Fassade(n) «code» Tests Model-To-Model Transformation Model-To-Text Transformation Abb. 8.1.: Verallgemeinerter Workow des Gargoyle-Test-Generators Der modellgetriebene Ansatz des Gargoyle-Test-Generators unterteilt sich in die drei in Abbildung 8.1 dargestellten Bereiche (a), (b) und (c). Bereich (a) umfasst die modellgetriebene Erzeugung mehrerer Test-Fassaden-Modelle und anschlieÿender Codegenerierung. Diese verbergen alle spezischen Details des zu testenden Systems, zum Beispiel das Domänenmodell und die Anwendungsfassade der Gargoyle-Anwendung. Auÿerdem stellen die Test-Fassaden zusätzliche Informationen über das gekapselte System zur Verfügung, die für die spätere Testfallerstellung und Codegenerierung benötigt werden. Der mit (b) markierte Bereich in Abbildung 8.1 beschreibt den Übergang zwischen den Test-Fassaden und den Komponenten zur Testfall- und Testinfrastrukturbeschreibung (Bereich (c)). Dies ist in der schematischen Übersicht nur als einzelne Modelltransformation unter Nutzung von Testmustern dargestellt. In der näheren Betrachtung der Testfallgenerierung in Kapitel 11 wird ein Test- Generatormodell eingeführt, das zur Konguration der Testfallerstellung dient. Aus diesem werden anschlieÿend die Testfälle generiert. Das in den Bereich (c) der Abbildung 8.1 fallende Test-Modell erfüllt die Aufgabe der systemunabhängigen Beschreibung von Testfällen. Es beschreibt die generierten Testfälle und die damit zusammenhängende Infrastruktur. Aus dem Test-Modell werden abschlieÿend die Quelltextartefakte für die automatische Testdurchführung und -auswertung generiert Entwicklungsumgebung Der modellgetriebene Ansatz zur Testgenerierung nutzt die Entwicklungsumgebung des Gargoyle-Generators. Die dort verwendeten Technologien haben sich bei der Entwicklung und im Einsatz des Gargoyle-Generators bewährt. Auÿerdem wäre ein Technologiewechsel zwischen Anwendungsentwicklung und Testgenerierung nicht sinnvoll. 64

77 Dies bedeutet, dass die hier vorgestellte modellgetriebene Methode weiterhin auf der Programmiersprache Java und der Entwicklungsplattform Eclipse in Kombination mit dem Eclipse Modeling Framework (EMF) basiert [Ecl12b]. Für die Modelltransformationen und Codegeneratoren werden die Sprachen Xtend und Xpand benutzt. Für die Beschreibung und Ausführung von Tests wird das JUnit- Rahmenwerk verwendet [Bec04]. Die Ausführung der Gargoyle-Anwendungen und der zugehörigen Tests geschieht unter Verwendung des Glasssh Application Servers [Gla09]. Für die automatisierte Durchführung von Tests wird der Hudson Continuous Integration Server [Ora12] genutzt Überblick Die nachfolgenden Kapitel stellen die einzelnen Komponenten des Gargoyle- Test-Generators vor. Zunächst beschreibt Kapitel 9 das Test-Modell und die damit zusammenhängende Spezikation von Tests und die Generierung von Testcode. Dabei werden erste Zusammenhänge zwischen dem Test-Modell und den Test-Fassaden vorgestellt, die das zu testende System von der Testschicht abstrahieren. Diese werden im Kapitel 10 betrachtet. Kapitel 11 befasst sich anschlieÿend mit der automatischen Testgenerierung, die die Verbindung zwischen Abstraktionsschicht und Testschicht herstellt. Zum Abschluss werden in Kapitel 12 die vorgestellten Konzepte zusammengefasst und die modellgetriebene Methode in ihrer Gesamtheit vorgestellt. Die Vorstellung der einzelnen Konzepte ist meist nur unter zusammenhängender Betrachtung von (Meta-)Modellen, Modelltransformationen, Codegeneratoren und dem aus den Modellen erzeugten Quelltext möglich. Daher bieten die nächsten Kapitel eine Sicht auf die einzelnen Konzepte, bei der jeweils auf alle relevanten Ebenen eingegangen wird. Zur Unterscheidung der einzelnen Betrachtungsebenen kann folgendes Schema verwendet werden: Meta-Modelle werden in der Regel durch UML-Modelle repräsentiert. Auf Modelltransformationen und Codegeneratoren wird an geeigneter Stelle informell im Text eingegangen. Modellinstanzen werden als EMF- Modelle in Form der bereits aus Abschnitt 3.2 bekannten baumbasierten Eclipse- Editoren dargestellt; Codebeispiele als Java-Quelltext. 65

78

79 9. Test-Modell Inhalt 9.1 Testmodellierung Testverwaltung Testautomatisierung Dieses Kapitel beschreibt das Gargoyle-Test-Modell zur plattformunabhängigen Beschreibung von Testfällen und die dazugehörige Codegenerierung. Diese umfasst sowohl die Generierung des Quellcodes für die Testfälle, als auch die Generierung der restlichen Infrastruktur zur automatischen Ausführung der Tests in einer Continuous Integration-Umgebung. Die Einführung der einzelnen Funktionen des Test-Modells und der angeschlossenen Codegeneratoren geschieht in mehreren Schritten. Zuerst wird der im vorangegangenen Kapitel in Abbildung 8.1 schematisch dargestellte Generator- Workow um weitere Details ergänzt. In den nachfolgenden drei Abschnitten werden die verschiedenen Teile des Test-Modells betrachtet. Im ersten Abschnitt wird auf die Modellierung und Generierung von Testfällen eingegangen und im Anschluss werden die Funktionen zur Verwaltung und Wiederverwendung von Testfällen und Testdaten vorgestellt. Der letzte Abschnitt befasst sich mit der die Tests umgebende Infrastruktur, die die automatische Ausführung der Tests in entsprechenden Continuous Integration-Umgebungen ermöglicht. Der Schichtenarchitektur aus Abschnitt der Prototypingphase folgend kann nun die Testschicht präzisiert werden. Die in Abbildung 9.1 auf Seite 68 dargestellte Schicht setzt auf die im Abschnitt erwähnte Abstraktionsschicht und deren Test-Fassaden auf. Hierbei ist hervorzuheben, dass die Testschicht keinerlei Wissen über das zu testende System benötigt, was durch die ausgegraute Gargoyle-Anwendungsschicht unterhalb der Abstraktionsschicht kenntlich gemacht wird. Für alle Aktionen zum Testen von Funktionen der Anwendungsschicht wird auf die Test-Fassaden zurückgegrien. Nähere Informationen dazu gibt Kapitel 10. Aufgrund der Abstraktion der Anwendungsschicht sind die hier vorgestellten Tests und das dazugehörige Test-Modell systemunabhängig und wiederverwendbar. Wie bereits in der Prototypingphase beschrieben, teilt sich die Testschicht in zwei Komponenten. Die Test-Servlet-Komponente bündelt alle für die Ausführung der Testfälle notwendigen Funktionen. Die Test-Wrapper- Komponente stellt die Funktionen zum Ausführen und Auswerten der Tests für entsprechende Continuous Integration-Umgebungen zur Verfügung. 67

80 Browser EJB Test-Wrapper (HtmlUnit) Test-Servlet (JUnit) Testschicht Test-Fassaden Abstraktionsschicht Gargoyle-Anwendung Komponente Kontrollfluss Abb. 9.1.: Tests in Gargoyle-Test-Schichtenarchitektur Zur Einordnung des Test-Modells und der Codegenerierung in die modellgetriebene Methode zur Testgenerierung dient Abbildung 9.2. Der hier abgebildete Teil des Gargoyle-Test-Generators entspricht dem Bereich (c) aus dem verallgemeinerten Workow in Abbildung 8.1 auf Seite 64. Bei den in diesem Kapitel betrachteten MDA-Komponenten handelt es sich um das Test-Meta-Modell zur Testbeschreibung und drei Codegeneratorkomponenten zur Erzeugung von Testfällen, des Test-Servlets und der Test-Wrapper-Komponente aus dem Test- Modell. Test-Modell Test-Quellcode «code» Tests «model» TestModel «code» Test-Servlet «code» Test-Wrapper Model-To-Text Transformation Abb. 9.2.: Workow zur Generierung der Testkomponenten 68

81 9.1. Testmodellierung Der erste Teil des Test-Modells dient der Modellierung von Testfällen. In diesem Abschnitt werden nacheinander verschiedene Details präsentiert, die mit Konzepten aus der Prototypingphase zusammenhängen. Dabei werden folgende Bereiche betrachtet: Grundlegende Struktur zur Testfallbeschreibung Klassizierung der einzelnen Testschritte Abbildung von Testschritten auf die Abstraktionsschicht Verwaltung von Abhängigkeiten zwischen einzelnen Testschritten Abschlieÿend wird ein Anwendungsbeispiel präsentiert, das alle vorgestellten Konzepte demonstriert Unit-Test-Strukturierung Die Struktur zur Spezikation von Tests im Test-Modell orientiert sich wie die Arbeiten von Javed et al. [JSW07] und Kiliclar [Kil10] am grundlegenden Aufbau von Unit-Test-Rahmenwerken. Die Abbildung 9.3 zeigt den Ausschnitt des Test-Modells, der zur Modellierung von Testfällen verwendet wird. TestSuite name : String 1 - suite 1 - testsuite 1 - testsuite * - tests 1 - setup 1 - teardown Test description : String Setup Teardown 1 * - teststeps TestStep Abb. 9.3.: Teststrukturierung im Test-Modell Testsuiten (TestSuite) fassen einzelne Testfälle zusammen. Sie besitzen Methoden zum Initialisieren (Setup) und Deinitialisieren (Teardown). Je Testsuite können ein oder mehrere Tests deniert werden (Test). Ein Test repräsentiert eine Menge von Testfällen mit identischen Testschritten; das heiÿt, nur die verwen- 69

82 deten Testdaten unterscheiden sich von Testfall zu Testfall. Ein Test deniert eine Menge von Testschritten (TestStep), die die Aktionen beschreiben, die bei der Durchführung eines Testfalls aus diesem Test ausgeführt werden. Der Quelltext 9.1 demonstriert die Test-Strukturierung anhand eines Auszugs der Forensystem-Tests. Jede Testsuite wird als Java-Klasse realisiert. Die Zeilen 2 bis 9 denieren die Methoden zum Setup und Teardown der Testsuite und der enthaltenen Testfälle. In den Zeilen 11 und 14 sind die einzelnen Testfälle und die dazugehörigen Methoden deniert. Quelltext 9.1: Beispiel einer Testsuite (Auszug) 1 p u b l i c c l a s s TestForum { p u b l i c s t a t i c void i n i t ( ) { /... / } p u b l i c s t a t i c void c l e a n ( ) { / NOOP / } 4 5 p r i v a t e s t a t i c TestDatabaseSetup dbsetup = new TestDatabaseSetup ( ) ; p u b l i c void setup ( ) throws DatabaseSetupException { 7 dbsetup. c l e a r A l l T a b l e s ( ) ; 8 } p u b l i c void teardown ( ) { / NOOP / } 10 p u b l i c void testattributesforumcreate1 ( ) { /... / } 12 p r i v a t e void testattributesforumcreate ( S t r i n g t i t l e ) { /... / } 13 p u b l i c void testduplicationforumcreate1 ( ) { /... / } 15 p r i v a t e void testduplicationforumcreate ( S t r i n g t i t l e ) { /... / } 16 } Testschrittklassizierung In Abbildung 9.4 sind die verschiedenen Klassen von Testschritten modelliert, die die im Abschnitt auf Seite 43 identizierten Testschritte abbilden. Die wichtigste Gruppe von Testschritten wird von der FacadeMethodCall-Klasse repräsentiert. Über diese Fassadenmethodenaufrufe interagieren die Tests mit den Test-Fassaden der Abstraktionsschicht, um mit dem System Under Test zu kommunizieren. Die ExpectedException-Klasse wird für die in Kapitel 6 eingeführten Fehlertests verwendet. Sie kapselt einen Aufruf einer Fassadenmethode und erwartet die Auslösung einer Ausnahme für den Methodenaufruf. Die Testschritt- Klasse LocalVariableToTestInterfaceParameterMapping realisiert die Übergabe von Testdaten an die Testmethode und wird im Abschnitt 9.2 beschrieben Test-Basismodell Bevor mit der Beschreibung der eigentlichen Testschritte begonnen werden kann, muss das dem Gargoyle-Test-Generator zugrundeliegende Basismodell eingeführt werden. Das Test-Basismodell (TestBaseModel) bildet die gemeinsame Schnittstelle zwischen allen Modellen des Gargoyle-Test-Generators. Das Basismodell erfüllt zwei grundlegende Aufgaben. Es deniert die abstrakte Fassaden- 70

83 TestStep LocalVariableToTestInterfaceParameterMapping 1 - facademethodcall 1 ExpectedException FacadeMethodCall - facademethod 1 1 FacadeMethod name : String TestBaseModel errormessage : String Abb. 9.4.: Testschrittklassikation im Test-Modell struktur, die auf der einen Seite von den Test-Fassaden der Abstraktionsschicht implementiert und auf der anderen Seite im Test-Modell zur Beschreibung von Testschritten benutzt wird. Auÿerdem beschreibt es ein einfaches Variablenund Typkonzept, das den Austausch von Typinformationen zwischen Modellen erlaubt. Ein Auszug des Meta-Modells des Test-Basismodells ist in Abbildung 9.5 dargestellt. Facade basepackagename : String 1 - facade * - methods FacadeMethod name : String Fassadenstruktur Typkonzept returntype FacadeType 1 - method * - parameters FacadeParameter facadetype Variable name : String «eattribute» /qualifiedname : String * type Type defaultinitializationvalue : String aslist : Boolean isordered : Boolean Abb. 9.5.: Test-Basismodell mit abstrakter Fassade Abstrakte Fassade Die linke Seite der Abbildung 9.5 zeigt die abstrakten Fassadenklassen, die die Verwendung von Fassaden in den verschiedenen Modellen des Gargoyle-Test- Generators erlauben. Mit ihrer Hilfe können die einzelnen Test-Fassaden der Abstraktionsschicht in den restlichen Modellen des Gargoyle-Test-Generators referenziert werden. 71

84 Für eine Fassade (Klasse Facade in Abbildung 9.5) kann eine beliebige Menge an Methoden deniert werden (FacadeMethod). Eine Methode besitzt beliebig viele Parameter (FacadeParameter) und einen Rückgabetypen (FacadeType). Methodenparameter haben ebenfalls einen Typen. Diese Fassadenstruktur bildet die Schnittstelle zwischen Tests und der zu testenden Anwendung. Alle Tests, die in den nachfolgenden Abschnitten beschrieben werden, greifen für Operationen auf dem System Under Test auf Fassadenmethoden zu, die diese Operationen kapseln. Weitere Informationen zu den einzelnen Test-Fassaden und den von ihnen bereitgestellten Operationen bietet Kapitel 10. Typkonzept Die in der Fassadenstruktur verwendeten Parameter und Typen unterliegen einem einfachen Typkonzept, das ebenfalls im Test-Basismodell deniert wird. Der rechte Teil der Abbildung 9.5 zeigt die abstrakten Basisklassen Variable und Type, die eine modellübergreifende Verwendung von Typen und Variablen erlaubt. Das Basismodell deniert dabei nur grundlegende Eigenschaften wie Typ- und Variablennamen sowie typabhängige Standardwerte und Attribute zur Verwendung von Typen mit Listen- bzw. Mengensemantik Anbindung von Fassaden Über die abstrakte Testfassade werden die Methoden der Test-Fassaden als Testschritte in die Tests eingebunden. Der rechte untere Teil der Abbildung 9.4 zeigt die Verknüpfung zwischen FacadeMethodCall und der abstrakten Facade- Method-Klasse. Um die in den Test-Fassaden denierten Methoden für die Beschreibung der einzelnen Testschritte verwenden zu können, müssen die Test-Fassaden in das Test- Modell importiert werden. Die EMF-basierten Modelleditoren bieten entsprechende Funktionen zum Laden von Ressourcen. Dadurch können die geladenen Test-Fassaden als Instanzen der abstrakten Fassaden-Typen des Test-Modells verwendet werden. Die Abbildung 9.6 zeigt einen Ausschnitt des Forensystem- Test-Modells, in dem die EJB-Fassade und die EJB-Assertion-Fassade als Ressourcen eingebunden sind (siehe Kapitel 10) Parametermappings Für die Testdurchführung sind geeignete Strukturen nötig um Methodenrückgabewerte, Parameter und Mappings zwischen Methodenaufrufen zu verwalten. Diese sind im rechten oberen Teil der Abbildung 9.7 zu sehen. Die Klasse Local- 72

85 Abb. 9.6.: Verwendung von Test-Fassaden als Ressourcen Test description : String 1 * - teststeps TestStep - localvariables 1 * - parametermapping - localvariable LocalVariable 1 * - localvariable Mappings zwischen Test- Fassaden und Testschritten LocalVariableToFacadeParameterMapping 1 * * 1 1 LocalVariableToFacadeMethodReturnTypeMapping FacadeMethodCall localvariabletofacademethodreturntypemapping facademethod FacadeMethod name : String TestBaseModel - method 1 - parameters * 1 - facadeparameter FacadeParameter - returntype facadetype returntype FacadeType Abb. 9.7.: Mapping zwischen Testschritten und Test-Fassaden Variable repräsentiert lokale Variablen innerhalb einer Testmethode. Die Menge der lokalen Variablen eines Tests ist über die Assoziation localvariables an die Test-Klasse angebunden. Über entsprechende Mappings zwischen lokalen Variablen und Methodenparametern sowie Methodenrückgabewerten können Parameter und Rückgaben von mehreren Fassadenmethodenaufrufen verknüpft werden. Dabei handelt es sich um die Klassen LocalVariableToFacadeParameterMapping und LocalVariableTo- FacadeMethodReturnTypeMapping. Jedes dieser Mappings ist einer Fassadenmethode zugeordnet, somit können lokale Variable mehrfach auf verschiedene Methodenparameter gemappt werden. Dies ist zum Beispiel bei Parametern für Fremd- und Primärschlüsselattribute von Entitäten hilfreich, da diese oftmals in mehreren aufeinanderfolgenden Testschritten verwendet werden. 73

86 Anwendungsbeispiel Abb. 9.8.: Ausschnitt des Forensystem-Test-Modells Ein Beispiel, das die verschiedenen Konzepte demonstriert, ist in Abbildung 9.8 und Quelltext 9.2 dargestellt. Dort ist eine Testsuite für die Thread-Entität des Forensystems und der darin enthaltene Test testattributesthreadcreate zu sehen. Die Abbildung zeigt einen Ausschnitt des Test-Modells des Forensystems mit einzelnen Fassadenmethodenaufrufen und dazugehörigen Parametermappings. In der markierten Zeile des Test-Modells sieht man ein Mapping zwischen der lokalen Variable _createforum_title und dem Fremdschlüsselparameter fk_title der Methode assertattributesforthread. Quelltext 9.2: Beispiel eines Testfalls mit Fassadenaufrufen (Auszug) 1 p u b l i c c l a s s TestThread { 2 p r i v a t e void t e s t A t t r i b u t e s T h r e a d C r e a t e ( i n t threadid, S t r i n g t i t l e, 3 S t r i n g t h r e a d T i t l e, boolean l o c k e d ) { 4 // l o c a l v a r i a b l e d e c l a r a t i o n 5 S t r i n g _createforum_title = n u l l ; 6 i n t _createthread_threadid = 1; 7 S t r i n g _createthread_threadtitle = n u l l ; 8 boolean _createthread_locked = f a l s e ; 9 // t e s t i n t e r f a c e mappings 10 _createthread_threadid = threadid ; 11 _createforum_title = t i t l e ; 12 _createthread_threadtitle = t h r e a d T i t l e ; 13 _createthread_locked = l o c k e d ; 14 // t e s t s t e p s 15 _ejbforumfacade. createforum ( _ createforum_ title ) ; 16 _ejbforumfacade. createthread ( _createthread_threadid, 17 _createforum_title, _ createthread_ threadtitle, 18 _createthread_locked ) ; 19 _ejbassertionforumfacade. a s s e r t A t t r i b u t e s F o r T h r e a d ( 20 _createforum_title, _createthread_threadid, 21 _ createthread_ threadtitle, _createthread_locked ) ; 22 } 23 } 74

87 Der aus einem Testfall des Forensystems generierte Quellcode ist auszugsweise im Quelltext 9.2 zu sehen. Die Testmethode in Zeile 2 besteht aus mehreren Testschritten. Zuerst werden die lokalen Variablen des Tests deklariert und anschlieÿend mit den Testdaten initialisiert, die an die Methode übergeben wurden (siehe Abschnitt 9.2). Die eigentliche Testdurchführung geschieht in den Zeilen 15 bis 21. Dort werden die dem Test zugeordneten Fassadenmethoden ausgeführt. Das Mapping der lokalen Variable _createforum_title auf den Fassadenparameter fk_title der assertattributesforthread-methode ist in Zeile 20 zu sehen Testverwaltung Die bisher gezeigte Teststruktur wird nun um Konzepte erweitert, die der Verwaltung von Testfällen und den dazugehörigen Testdaten dienen. Dadurch können die im vorherigen Abschnitt modellierten Tests für mehrere Testfälle wiederverwendet werden Testschnittstellen Wie bereits erwähnt stellt ein Test eine Menge von Testfällen mit gemeinsamem Testablauf dar. Dieser Testablauf ist durch die dem Test zugeordneten Testschritte deniert. Um den Testablauf zusammenzufassen und mit den zu einem Testfall gehörenden Testdaten zu initialisieren, wird einem Test eine Testschnittstelle (TestInterface) mit einer Menge von Parametern (TestParameter) zugeordnet. Die für einen Test denierten Testparameter stellen die für einen Testfall variierbaren Testdaten dar. Abbildung 9.9 zeigt die dem Test zugeordnete Testschnittstelle mit ihren Testparametern. Auÿerdem kann jetzt die Rolle des LocalVariableToTestInterfaceParameterMapping-Testschritts präzisiert werden. Dieses Mapping dient zur Übertragung der über die Testschnittstelle übergebenen Testdaten auf die lokalen Variablen der Testmethode. Test - testinterface TestInterface - testparameters TestParameter description : String localvariables * name : String LocalVariable 1 * 1 - testparameter 1 - localvariable * - teststeps TestStep 1 LocalVariableToTestInterfaceParameterMapping 1 Abb. 9.9.: Test-Schnittstelle und Parameter 75

88 Bei der Codegenerierung wird eine Methode passend zur Testschnittstelle erzeugt, die alle Testschritte des Tests implementiert. Die Parameter der Methode entsprechen den Testparametern der Testschnittstelle. Mit Hilfe der generierten Methode können die dem Test zugeordneten Testfälle ausgeführt werden. Im Quelltextbeispiel 9.2 auf Seite 74 ist die entsprechende Testmethode in Zeile 2 zu sehen. Die über die LocalVariableToTestInterfaceParameterMapping-Klasse beschriebenen Mappings zwischen den Testparametern und den zugehörigen lokalen Variablen ist in den Zeilen 10 bis 13 abgebildet Testinstanzen Testfälle werden im Test-Modell als sogenannte Testinstanzen (TestInstance) repräsentiert, die der untere Teil der Abbildung 9.10 zeigt. Diese sind ebenfalls einem Test zugeordnet. Testinstanzen enthalten eine Menge von Variablen (ParameterInstance), die Testdaten für die Testparameter der Testmethode (TestInterface) spezizieren. Testinstanzen stellen somit einzelne Testfälle dar. Testdaten für Testfälle können entweder direkt deniert werden (LocalParameterInstance) oder aus einer Menge von denierten Standardwerten ausgewählt werden. Diese Standardwerte (DefaultParameter) werden in einem Container (DefaultParameterContainer) deniert, die im Test-Modell gespeichert werden. Standardwerte bieten den Vorteil, dass sie auÿerhalb der Tests in einer separaten Klasse deniert werden. Über diese können die Testdaten der einzelnen Testfälle verwaltet werden. TestModelRoot 1 - testmodelroot * - testsuites TestSuite name : String 1 - suite 1 * - defaultparametercontainer DefaultParameterContainer name : String 1 - defaultparameter * Standardwerte - defaultparameterinstance * LocalParameterInstance DefaultParameterInstance value : String Testfälle DefaultParameter value : String - defaultparameter 1 - testinstances TestInstance - parameterinstances ParameterInstance * 1 * * * - tests 1 - test Testmethode - parameter 1 Test - testinterface TestInterface - testparameters TestParameter description : String 1 1 name : String 1 * Abb : Standardwerte, Testfälle und Testmethoden 76

89 Anwendungsbeispiel Abbildung 9.11 zeigt einen Auszug des Forensystem-Test-Modells. Im oberen Teil der abgebildeten Liste ist eine Testschnittstelle und deren Testparameter zu sehen, unterhalb eine dazugehörige Testinstanz. Abb : Denition der Test-Schnittstelle und einer Testinstanz Der aus dem Test-Modell generierte Testfall ist in Quelltext 9.3 abgebildet. Zeile 3 zeigt die Testschnittstelle des Tests, die Methode testattributesthreadcreate1 in den Zeilen 7 bis 14 entspricht einem Testfall, der über eine Testinstanz beschrieben wird. In Zeile 14 der Methode wird die Testmethode mit den Testschritten aus Zeile 3 aufgerufen. Die Testinstanz benutzt Standardwerte, die in der Klasse ThreadTestDefaults in den Zeilen 17 bis 22 deniert werden. Quelltext 9.3: Testschnittstelle, Testfall und Standardwerte (Auszug) 1 p u b l i c c l a s s TestThread { 2 /... / 3 p r i v a t e void t e s t A t t r i b u t e s T h r e a d C r e a t e ( i n t threadid, S t r i n g t i t l e, 4 S t r i n g t h r e a d T i t l e, boolean l o c k e d ) { 5 /... / 6 } p u b l i c void t e s t A t t r i b u t e s T h r e a d C r e a t e 1 ( ) { 8 i n t threadid = ThreadTestDefaults. defaultthreadid ; 9 S t r i n g t i t l e = ThreadTestDefaults. d e f a u l t T i t l e ; 10 S t r i n g t h r e a d T i t l e = ThreadTestDefaults. d e f a u l t T h r e a d T i t l e ; 11 boolean l o c k e d = ThreadTestDefaults. defaultlocked ; t e s t A t t r i b u t e s T h r e a d C r e a t e ( threadid, t i t l e, t h r e a d T i t l e, l o c k e d ) ; 14 } 15 } p u b l i c f i n a l c l a s s ThreadTestDefaults { 18 p u b l i c s t a t i c f i n a l i n t defaultthreadid = 1 ; 19 p u b l i c s t a t i c f i n a l S t r i n g d e f a u l t T i t l e = " defaulttitle " ; 20 p u b l i c s t a t i c f i n a l S t r i n g d e f a u l t T h r e a d T i t l e = " defaultthreadtitle " ; 21 p u b l i c s t a t i c f i n a l boolean defaultlocked = f a l s e ; 22 } 77

90 9.3. Testautomatisierung Abschlieÿend wird die Codegenerierung für die Test-Wrapper-Komponente betrachtet. Diese realisiert die automatische Ausführung und Auswertung der Tests über die Continuous Integration-Umgebung. Die Test-Wrapper-Komponente führt die für sie denierten Testfälle aus, wie in Quelltext 9.4 abgebildet. Dabei wird zweistug vorgegangen. Der erste Testfall in Zeile 3 dient zur Ausführung der Tests im Test-Servlet und zur Speicherung der Testergebnisse. Zuerst wird die entsprechende Testsuite im Test-Servlet ausgeführt. Die dazu nötige URL wird aus der Test-Servlet-Konguration und dem in den Zeilen 4 und 5 übergebenen Namen des Tests gebildet. Das Test-Servlet generiert bei der Ausführung eine Ausgabe des Testverlaufs wie in Abbildung 5.3 auf Seite 38. Diese Ausgabe wird nun nach den einzelnen Testfällen durchsucht und deren Ergebnis gespeichert. Dazu wird für jeden Testfall die Methode checktestcase aufgerufen, wie in den Zeilen 7 und 8 abgebildet. Bisher würde in der Continuous Integration-Umgebung nur zu erkennen sein, dass entweder alle Test erfolgreich waren oder mindestens ein Testfall des Test- Servlets fehlgeschlagen ist. Um die Ergebnisse jedes einzelnen Testfalls sehen zu können, müssen die Ergebnisse der Testausführung aus dem bereits vorgestellten Testfall in separaten Testfällen ausgewertet werden. Dazu werden die gespeicherten Ergebnisse der Testausführung des Test-Servlets verwendet. Entsprechende Methoden sind in den Zeilen 13 und 17 abgebildet. Diese stellen jeweils einen Testfall des Test-Servlets dar. Die aufgerufene Methode checkresultfor greift auf die gespeicherten Testergebnisse zu und gibt das entsprechende Ergebnis an die Unit-Test-Komponente des Test-Wrappers weiter. Quelltext 9.4: Testausführung und -auswertung (Auszug) 1 p u b l i c c l a s s TestThread extends ForumSystemJ2EEIntegrationTestOnGlassfish 2 { p u b l i c void c a l l T e s t ( ) { 4 callthetestwebsite ( gettesturlstring ( 5 " de. rwth. swc. gargoyle. forumsystem. tests. TestThread ") ) ; 6 7 checktestcase ( " testattributesthreadcreate1 ") ; 8 checktestcase ( " testduplicationthreadcreate1 ") ; 9 10 c l o s e C o n n e c t i o n ( ) ; 11 } 12 p u b l i c void t e s t A t t r i b u t e s T h r e a d C r e a t e 1 ( ) { 14 checkresultfor ( " testattributesthreadcreate1 ") ; 15 } 16 p u b l i c void t e s t D u p l i c a t i o n T h r e a d C r e a t e 1 ( ) { 18 checkresultfor ( " testduplicationthreadcreate1 ") ; 19 } 20 } 78

91 10. Test-Fassaden Inhalt 10.1 Erweiterung des Test-Basismodells EJB-Fassade Entity-Fassade EJB-Assertion-Fassade Dieses Kapitel befasst sich hauptsächlich mit den Konzepten zur Erfüllung der Anforderung, Tests innerhalb des Test-Generators unabhängig vom zu testenden System beschreiben zu können. Dazu musste ein geeigneter Weg gefunden werden, die zu testenden Anwendung an den Generator anzubinden, ohne die Systemunabhängigkeit der Testbeschreibung zu beeinträchtigen. Als geeignete Lösung für dieses Problem zeigte sich das schon im Gargoyle-Generator verwendete Konzept der Fassaden bzw. Anwendungsfassaden (siehe 2.1.4). Indem das zu testende System durch eine oder mehrere Fassaden gekapselt wird, können alle systemspezischen Informationen im Kontext der Testbeschreibung und Ausführung verborgen werden. Zu Beginn dieses Kapitels werden die Fassaden in die für die Testdurchführung verwendete Schichtenarchitektur eingeordnet. Anschlieÿend wird der modellgetriebene Ansatz mit Meta-Modellen, Modellen, Modelltransformationen und Codegeneratoren zur Beschreibung, Generierung und Implementierung der einzelnen Test-Fassaden beschrieben. Das Test-Fassaden erfüllen sowohl für die Schichtenarchitektur als auch für den modellgetriebenen Ansatz verschiedene Aufgaben. Sie verbergen wie bereits erwähnt systemspezische Details vor der Testausführungsschicht. Auÿerdem fassen sie einzelne Operationen zu geeigneten testrelevanten Operationen zusammen. Eine weitere wichtige Aufgabe liegt in der Bereitstellung von zusätzlichen Informationen zu den über die Fassaden implementierten Methoden, die bei der modellgetriebenen Generierung von Testfällen benötigt werden. Zu Beginn der Konzeptionsphase wurden drei Test-Fassaden identiziert, die zur Abstraktion von Gargoyle-Anwendungen dienen. Die EJB-Fassade beschreibt die Methoden der Gargoyle-Anwendungsfassade. Daneben kapselt die Entity- Fassade den Zugri auf das Domänenmodell. Die EJB-Assertion-Fassade kombiniert die von der Entity-Fassade und der EJB-Fassade bereitgestellten Methoden, um die für die Ausführung von Testfällen notwendigen Prüfschritte zu realisieren. Die drei beschriebenen Test-Fassaden bilden die Schnittstelle zwischen dem zu testenden System und der Testausführungsschicht. Abbildung

92 EJB Tests Tests EJB-Assertion-Fassade Entity-Fassade EJB-Fassade Abstraktionsschicht Entities Anwendungsfassade Controller DAO Gargoyle-Anwendung Komponente Kontrollfluss... Abb : Fassaden in Gargoyle-Test-Schichtenarchitektur stellt die Abstraktionsschicht mit den drei Test-Fassaden dar. Die Abstraktionsschicht verbirgt die anwendungsspezischen Details und deren Domänenmodell für die Testausführungsschicht. Dabei bauen die einzelnen Fassaden wie bereits beschrieben aufeinander auf, was am Zugri der EJB-Assertion-Fassade auf die EJB-Fassade und die Entity-Fassade in der Abstraktionsschicht erkennbar ist. Im modellgetriebenen Ansatz werden diese Test-Fassaden jeweils durch Modelle repräsentiert. Die entsprechenden Meta-Modelle sind das EJB-Fassadenmodell, das Entity-Fassadenmodell und das EJB-Assertion-Fassadenmodell. Diese referenzieren das Entity-Modell und das EJB-Modell der Gargoyle-Umgebung (siehe 2.5.2), um entsprechende Zugrismethoden für die Anwendungsfassade, das Domänenmodell und darauf aufsetzende Prüfmethoden zu beschreiben. Mit den bereits vorhandenen Informationen kann die modellgetriebene Methode für die Generierung der Test-Fassaden genauer speziziert werden. Abbildung 10.2 verfeinert den verallgemeinerten Gargoyle-Workow aus Abbildung 8.1 von Seite 64. Ausgehend von den Gargoyle-Modellen auf der linken Seite werden die Modelle der Test-Fassaden durch Modelltransformationen erzeugt. Auf der rechten Seite sind die per Codegenerator erstellten Fassaden-Implementierungen abgebildet. Einzelheiten zu den dargestellten Fassadenmodellen und den dazugehörigen Modelltransformations- und Codegenerierungsschritten werden in den jeweiligen Abschnitten dieses Kapitels vorgestellt. 80

93 Gargoyle-Modelle Test-Fassadenmodelle Fassaden-Quellcode «model» EntityModel «model» EntityFacadeModel «code» EntityFacade «model» EJBModel «model» EJBFacadeModel «code» EJBFacade Model-To-Model Transformation Model-To-Text Transformation «model» EJBAssertionFacadeModel «code» EJBAssertionFacade Abb : Workow zur Generierung der Test-Fassaden Wie bereits in Abschnitt beschrieben, nutzen die Test-Fassaden die abstrakte Fassadenstruktur des Test-Basismodells. Das Test-Modell kann durch Nutzung der abstrakten Fassadentypen auf die einzelnen Test-Fassaden referenzieren, ohne dass Abhängigkeiten von den entsprechenden Fassaden-Modellen entstehen. Im folgenden Abschnitt werden zusätzliche Details zum Test-Basismodell präsentiert. Anschlieÿend werden die drei Test-Fassaden des Gargoyle-Test-Generators vorgestellt Erweiterung des Test-Basismodells Im Abschnitt wurde noch nicht das komplette Test-Basismodell beschrieben, was an dieser Stelle nachgeholt wird. Abbildung 10.3 zeigt die Struktur zur Konguration der einzelnen Fassaden für die Codegenerierung. Die einzelnen Codegeneratorkomponenten des Gargoyle-Test-Generators benötigen diese Informationen, um einheitliche Namen und Paketnamen für die Benutzung der Test-Fassaden zu generieren. Dabei werden bis zu vier verschiedene Kongurationen benötigt, die bei der Codegenerierung zur Anwendung kommen. Die Klasse FacadeConguration ist über verschiedene Assoziationen an die Fassadenklasse angebunden. Jede der Kongurationen deniert einen Klassen- und einen Paketnamen, die bei der Codegenerierung für Klassen- und Paketnamen sowie Import-, Kongurationsund Konstruktoranweisungen verwendet werden. 81

94 Facade basepackagename : String 1 - facadeconfiguration implementingfacadeconfiguration facadedsystemconfiguration 0..1 FacadeConfiguration name : String packagename : String 1 - initializationconfiguration 0..1 Abb : Fassadenkonguration im Test-Basismodell Die einzelnen Assoziationen repräsentieren dabei verschiedene Kongurationen: facadeconguration deniert die Klassen- und Paketnamen für die öentliche Schnittstelle der Fassade, realisiert als Java-Interface implementingfacadeconguration deniert die Klassen- und Paketnamen der Implementierung der Fassade facadedsystemconguration deniert das von der Fassade gekapselte System initializationconguration beschreibt den Klassen- und Paketnamen einer Komponente, die die Fassade initialisiert Quelltext 10.1 demonstriert, wie sich die Fassadenkonguration auf die Codegenerierung auswirkt. Die Zeilen 1 bis 5 zeigen die über facadeconguration beschriebene Schnittstelle der EJB-Fassade. Deren Implementierung wird durch implementingfacadeconguration deniert und ist in den Zeilen 7 bis 19 abgebildet. In Zeile 8 wird die durch facadedsystemconguration kongurierte Anwendungsfassade der Gargoyle-Anwendung instantiiert, über die in den Zeilen 14 und 17 Methoden der Gargoyle-Anwendungsfassade aufgerufen werden. Die Initialisierung durch die in initializationconguration angegebene TestServlet-Komponente erfolgt in Zeile 10. Quelltext 10.1: Anwendungsbeispiel für Fassadenkongurationen 1 p u b l i c i n t e r f a c e EJBForumFacade { 2 p u b l i c void i n i t ( ) ; 3 p u b l i c void createforum ( S t r i n g t i t l e ) ; 4 p u b l i c void updateforum ( S t r i n g newtitle, S t r i n g o l d T i t l e ) ; 5 } 6 7 p u b l i c c l a s s EJBForumFacadeImpl implements EJBForumFacade { 8 p r i v a t e s t a t i c ForumFacadeLocal _ejbforumfacade ; 9 p u b l i c void i n i t ( ) { 10 _ejbforumfacade = T e s t S e r v l e t. TheForumFacadeLocal ( ) ; 11 } p u b l i c void createforum ( S t r i n g t i t l e ) { 14 _ejbforumfacade. createforum ( t i t l e ) ; 15 } 16 p u b l i c void updateforum ( S t r i n g newtitle, S t r i n g o l d T i t l e ) { 17 _ejbforumfacade. updateforum ( newtitle, o l d T i t l e ) ; 18 } 19 } 82

95 10.2. EJB-Fassade Die EJB-Fassade bildet die Schnittstelle zur Anwendungsfassade der zu testenden Gargoyle-Anwendung. Damit bildet sie eine der zentralen Komponenten des Gargoyle-Test-Generators. Sie spiegelt die von der Gargoyle-Anwendungsfassade bereitgestellten Methoden und leitet Aufrufe an die Anwendungsfassade weiter. Das EJB-Fassadenmodell verknüpft das der Anwendung zugrundeliegende EJB-Modell mit der abstrakten Test-Fassade aus dem Test-Basismodell. Es wird per Modelltransformation aus dem EJB-Modell der zu testenden Gargoyle-Anwendung erzeugt. Im Abschnitt wird die Spezialisierung der abstrakten Test-Fassade und das Mapping zwischen EJB-Modell und EJB-Fassadenmodell der Gargoyle-Anwendung näher beschrieben. Dabei werden die einzelnen Methoden und Parameter der Gargoyle-Anwendungsfassade im EJB-Fassadenmodell anhand ihrer Rolle für das implementierte Informationssystem in verschiedene Methodenund Parametertypen eingeordnet. Diese Methoden- und Parametertypen sind in vielen Fällen nicht direkt aus dem Entity- und EJB-Modell der zu testenden Gargoyle-Anwendung ablesbar. Daher wird diese Klassizierung nachträglich im EJB-Fassadenmodell vorgenommen. Dies erleichtert die nachfolgende Testfallerzeugung. Eine Übersicht über die erfolgte Methoden- und Parameterklassi- kation erfolgt im Abschnitt Modelldetails Die abstrakten Modellfassaden des Test-Basismodells aus Abschnitt werden im EJB-Fassadenmodell durch Vererbung spezialisiert. Abbildung 10.4 zeigt die abgeleiteten Fassaden-Klassen EJBFacade, EJBFacadeMethod, EJBFacade- Parameter und drei Spezialisierungen der FacadeType-Klasse. EJBEntityType beschreibt Typen für Entitäten des Domänenmodells und EJBAttributeType Typen der Entitätsattribute. EJBPrimitiveType stellt Typen dar, die nicht im Entity-Modell für Entitäten oder Attribute deniert sind. Darunter fällt unter anderem der Typ void, der als Rückgabetyp für Methoden verwendet wird, die kein Ergebnis zurückliefern. Mit Hilfe der vorgestellten Klassen können nun konkrete Fassadenmodelle erzeugt werden, die anschlieÿend in den anderen Modellen des Gargoyle-Test- Generators referenziert werden können. Um mit der EJB-Fassade die Anwendungsfassade der Gargoyle-Anwendung beschreiben zu können, werden die EJBspezischen Fassadenklassen bei ihrer Erzeugung durch die Modelltransformation mit dem EJB-Modell verknüpft. Dieses Mapping zwischen Fassade und EJB-Modell wird in Abbildung 10.5 gezeigt. Links sind die Klassen der EJB- Fassade zu sehen, auf der rechten Seite die Klassen des EJB-Modells. 83

96 Test-Basismodell Facade EJB-Fassadenmodell EJBFacade basepackagename : String 1 - facade * - methods 1 FacadeMethod name : String 1 - method EJBFacadeMethod * - parameters FacadeParameter EJBFacadeParameter 1 EJBEntityType 1 - returntype FacadeType 1 - facadetype EJBPrimitiveType EJBAttributeType Abb : Instantiierung der EJB-Fassade EJB-Fassadenmodell EJBFacade EJB-Modell - mappedejbabstractbean AbstractBean 1 1 name : String 1 + bean * - methods EJBFacadeMethod - mappedejbfacademethod FacadeMethod Method 1 1 name : String + method parameter * EJBFacadeParameter - mappedejbparameter Parameter 1 1 name : String 1 + type 1 + returntype 1 EJBEntityType - mappedtypeforentity TypeForEntity TypeApplication 1 1 aslist : Boolean EJBPrimitiveType - mappedprimitivetype PrimitiveType 1 1 primitivename : String EJBAttributeType - mappedsametypeasattribute 1 1 SameTypeAsAttribute Abb : Mapping zwischen EJB-Fassade und EJB-Modell 84

97 Dieser Teil des EJB-Fassadenmodells oenbart einige Details zur Modelltransformation vom EJB-Modell in das EJB-Fassadenmodell. Für jede Instanz einer AbstractBean-Klasse des EJB-Modells, die eine Anwendungsfassade beschreibt, wird eine entsprechende EJB-Fassade erzeugt. Eine AbstractBean-Instanz beschreibt genau dann eine Anwendungsfassade, wenn sie mindestens eine als FacadeMethod klassizierte Methode enthält. Für diese Fassadenmethoden werden entsprechende Methoden für die EJB-Fassade erzeugt. Anschlieÿend werden die Parameter und der Rückgabetyp für jede der Fassadenmethoden des EJB- Modells auf die entsprechende Methode des EJB-Fassadenmodells übertragen. Dazu werden Instanzen der EJB-Fassadenparameter und EJB-Fassadentypen erzeugt. Hier kommt die bereits erwähnte Unterteilung in Entity-, Attributsund primitive Typen zur Anwendung. Diese entspricht der Typspezialisierung im EJB-Modell, die zwischen TypeForEntity, SameTypeAsAttribute und PrimitiveType unterscheidet. Mit den bisher vorgestellten Konzepten kann der Quelltext der EJB-Fassade generiert werden, da die durch die Fassade bereitgestellten Methoden genau die Fassadenmethoden der Gargoyle-Anwendung darstellen. Die den EJB-Fassadenmethoden zugeordneten Parameter werden bei der Codegenerierung sowohl für die Schnittstelle der jeweiligen Methode, als auch für den Aufruf der gekapselten Methode der Gargoyle-Anwendungsfassade verwendet. Ein Quelltextbeispiel der generierten EJB-Fassade wurde bereits in Abbildung 10.1 auf Seite 82 präsentiert. Die EJB-Fassadenmethode updateforum in Zeile 16 delegiert in Zeile 17 den Aufruf an die entsprechende Methode der Gargoyle-Anwendungsfassade. Die Signaturen der Methoden sind identisch; die Parameter der EJB-Fassadenmethode werden unverändert an die Methode der Gargoyle-Anwendungsfassade übergeben Methoden- und Parameterklassikation Die vorgestellten Konzepte sind ausreichend, um die Implementierung der EJB- Fassade zu generieren. Dieser Abschnitt beschäftigt sich daher mit der Erweiterung der Modelle um Informationen, die relevant für die Generierung von Tests und der EJB-Assertion-Fassade sind. Dabei werden zwei Bereiche betrachtet: Auf der einen Seite werden die Fassadenmethoden anhand ihrer Semantik innerhalb des Informationssystems klassiziert. Dies ist für die Auswahl von Testmustern während der Testgenerierung notwendig. Auf der anderen Seite müssen die Parameter der Fassadenmethoden klassiziert werden, um auf den Kompositionsbeziehungen zwischen den Entitäten des Domänenmodells basierende Abhängigkeiten zwischen den Fassadenmethoden auösen zu können. Dies betrit insbesondere die Parameter für Primär- und Fremdschlüssel in den Methodensignaturen. Das Problem der Abhängigkeiten zwischen Methoden für die Erzeugung von Testszenarien wurde bereits in der Prototypingphase im Abschnitt identiziert. 85

98 Methodenklassikation zur Testgenerierung Jede der Methoden der Anwendungsfassade der Gargoyle-Anwendung erfüllt eine bestimmte Operation auf den Daten des Informationssystems. Dabei handelt es sich um die bereits erwähnten CRUD-Funktionen (Create, Read, Update, Delete) für die Entitäten des Domänenmodells. Sieben verschiedene Methodentypen wurden für die Gargoyle-Anwendungsfassade identiziert. Diese werden durch Klassen im EJB-Fassadenmodell repräsentiert, die von der abstrakten Basisklasse EJBFacadeMethod erben. Eine Übersicht über die verschiedenen Methodenklassen bietet Abbildung EJBFacadeMethod - entity * 1 Entity GetAllMethod CreateMethod GetEntityMethod UpdateMethod AssignMethod DeleteMethod UnassignMethod Abb : Methodenklassikation im EJB-Fassadenmodell und Mapping auf Entity-Modell Jeder Methodentyp beschreibt den Zugri auf die mit der EJBFacadeMethod- Basisklasse assoziierten Entität. CreateMethod, GetEntityMethod, UpdateMethod und DeleteMethod stellen die entsprechenden CRUD-Methoden dar. Die Zugrisfunktionen auf die Liste aller Entitäten der Top-Level-Elemente (siehe Abschnitt 2.5.2) werden über die GetAllMethod-Klasse beschrieben. Die Klassen AssignMethod und UnassignMethod dienen zur Verwaltung der Assoziationen zwischen den Entitäten des Informationssystems. Durch die erfolgte Klassikation der Methodentypen ist es während der Testgenerierung möglich, die zum jeweiligen Methodentypen passenden Testmuster anzuwenden. Dabei muss nicht mehr auf die Identizierung von Methoden über ihren Namen oder auf das jeweilige EJB- oder Entity-Modell zurückgegrien werden. Parameterklassikation für Methodenabhängigkeiten Eine ähnliche Klassizierung wird auch für die Methodenparameter vorgenommen. Dabei werden die Parameter der Fassadenmethoden anhand ihrer Rolle 86

99 im Domänenmodell in Primärschlüssel, Fremdschlüssel und Wertattribute unterteilt. Abbildung 10.7 zeigt einen Ausschnitt des EJB-Fassadenmodells mit den vier Parametertypen und ihrem Mapping auf die Entitäten und Attributen des Entity-Modells. Primärschlüssel werden durch die Klassen PrimaryKeyParameter und New- PrimaryKeyParameter repräsentiert, das entsprechende Attribut des Domänenmodells wird über die Assoziation mappedpk referenziert. Die Klasse New- PrimaryKeyParameter deckt einen Spezialfall für Update-Methoden ab, in dem sowohl der aktuelle, als auch der neue Primärschlüssel beim Methodenaufruf übergeben werden muss. Somit kann zwischen beiden Primärschlüsseln, die auf das gleiche Attribut verweisen, unterschieden werden. Die Fremdschlüssel von Entitäten werden durch die Klasse ForeignKeyParameter dargestellt. Sie referenzieren die entsprechenden Fremdschlüssel und die damit verbundene Entität über die Assoziation mappedfk. Alle Parameter, die kein Primär- oder Fremdschlüsselattribut einer Entität repräsentieren, werden als ValueParameter klassiziert. Sie beschreiben einfache Attribute der jeweiligen Entität. EJBFacadeParameter ForeignKeyParameter - mappedfk * 1 * ForeignKey PrimaryKeyParameter * 1 + origin Entity 1 + entity EJB-Fassadenmodell Entity-Modell NewPrimaryKeyParameter ValueParameter - mappedpk * 1 - mappedattribute 1 * + attribute Attribute Abb : Parameterklassikation im EJB-Fassadenmodell und Mapping auf Entity-Modell Auch die Unterteilung der Parameter der EJB-Fassadenmethoden in verschiedene Klassen erfüllen Aufgaben zur Test- bzw. weiteren Fassadengenerierung. Über die Primär- und Fremdschlüssel lassen sich Abhängigkeiten zwischen Entitäten auösen. Kombiniert mit den bereits klassizierten Create-Methoden für die betreenden Entitäten kann während der Testgenerierung das im Abschnitt beschriebene In-Line Setup [Mes07] und das damit verbundene Parametermapping zwischen den einzelnen Testschritten der Testfälle konstruiert werden. Diese Abhängigkeiten sind ebenfalls für die Generierung der EJB- Assertion-Fassade notwendig, da die dortigen Prüfschritte heuristisch anhand der Attributklassikation generiert werden. Weitere Informationen dazu bietet der Abschnitte zur EJB-Assertion-Fassade (10.4) und das Kapitel 11, das auf die Testgenerierung eingeht. 87

100 Abbildung 10.8 fasst die vorgestellten Klassikationen und Modellmappings anhand der EJB-Fassade des Forensystems zusammen. In der Abbildung sind die Methoden createuser und updatepost mit ihren Parametern zu sehen. Im Gegensatz zur Gargoyle-Anwendungsfassade des Forensystem-EJB-Modells aus Abbildung 3.4 auf Seite 28 ist die Semantik der Methoden und ihrer Parameter klar am Methoden- bzw. Parametertypen erkennbar. Im unteren Teil der Abbildung sind Details zur selektierten Methode updatepost sichtbar, unter anderem das Mapping zur Fassadenmethode updatepost der Gargoyle-Anwendungsfassade. Abb : EJB-Fassade des Forensystems (Auszug) Entity-Fassade Die Entity-Fassade dient zur Abstraktion des Domänenmodells. Für die Beschreibung von Testschritten im Test-Modell ist es aufgrund der gewünschten Unabhängigkeit vom zu testenden System nicht möglich, auf Objekte oder Klassen des Domänenmodells zuzugreifen. Die Entity-Fassade kapselt die Domänenklassen und stellt Zugrismethoden für deren Attribute und Assoziationen bereit. Ähnlich wie die EJB-Fassade klassiziert sie die einzelnen Methoden und Parameter der Entity-Fassade, um bei der Testfallgenerierung einfacher auf die Fassadenmethoden zurückgreifen zu können. Die Entity-Fassade wird im vorgestellten modellgetriebenen Ansatz nur von der EJB-Assertion-Fassade für die Prüfung der Attribute und Assoziationen von 88

101 Facade EntityFacade * 0..1 Entity basepackagename : String - mappedentity - entity 1 FacadeMethod EntityFacadeMethod * name : String entitymethodname : String - mappedentity 1 EqualsMethod GetterMethod * Test-Basismodell FacadeParameter Entity-Fassadenmodell EntityFacadeParameter Entity- Modell FacadeType EntityFacadeType EntityType * PrimitiveType primitivename : String EntityAttributeType * 1 - mappedattribute attribute Attribute Abb : Instantiierung der Entity-Fassade und Mapping zum Entity-Modell Entitäten genutzt. Daher bildet die Entity-Fassade nur die Methoden für den lesenden Zugri in Form von Getter- und Equals-Methoden für die Entitäten des Domänenmodells ab. Diese sind im Entity-Modell nicht explizit modelliert, sondern werden per Heuristik bei der Codegenerierung erzeugt. Dieses Verfahren wird bei der modellgetriebenen Erzeugung des Entity-Fassadenmodells nachgebildet, um die Fassadenmethoden der Entity-Fassade zu konstruieren. Auch das Entity-Fassadenmodell verwendet die abstrakte Fassadenstruktur des Test-Basismodells und leitet die Entity-Fassadenklassen davon ab. Der mittlere Teil der Abbildung 10.9 zeigt die Fassadenklassen des Entity-Fassadenmodells, auf der rechten Seite ist das Mapping auf die Entitäten und Attribute des Entity- Modells abgebildet. Für jede Entität des Entity-Modells wird eine Instanz der EntityFacade generiert. Fassadenmethoden werden durch die Klasse EntityFacadeMethod repräsentiert und durch die Klassen EqualsMethod und GetterMethod spezialisiert. EqualsMethod beschreibt die gleichnamige Methode zum Vergleich einer Entität mit einem anderen Objekt. GetterMethod beschreibt die Zugrismethode für ein Attribut, das über die Assoziation attribute referenziert wird. Für die Methoden- 89

102 parameter der Entity-Fassade wird die Klasse EntityFacadeParameter verwendet. Jeder Getter-Methode wird nur ein einziger Parameter zugeordnet, der die Entität des abzurufenden Attributwerts repräsentiert. Für Equals-Methoden wird neben dem Parameter für die Entität noch ein weiterer Parameter erzeugt, der das mit der Entität zu vergleichende Objekt beschreibt. Die EntityFacade- Type-Klasse beschreibt die Typen der Entity-Fassade. Diese werden durch die abgeleiteten Klassen EntityType, EntityAttributeType und PrimitiveType näher speziziert. Entity-Typen stehen dabei für den Typen der über mappedentity referenzierten Entität und Attribut-Typen für den Typen des über mappedattribute referenzierten Entitäts-Attributs. Primitive Typen werden für die Equals- Methode verwendet, um den Typen Object für das mit der Entität zu vergleichende Objekt und den Rückgabetypen boolean für das Ergebnis des Vergleichs zu repräsentieren. Die Abbildungen und Quelltext 10.2 zeigen Auszüge des Entity-Fassadenmodells und des generierten Quelltextes der Entität User. Dabei sind verschiedene Getter- und die Equals-Methode abgebildet. Abb : Entity-Fassadenmodell des Forensystems (Auszug) Quelltext 10.2: Quelltext der Entity-Fassade des Forensystems (Auszug) 1 p u b l i c c l a s s EntityUserFacadeImpl implements EntityUserFacade { 2 p u b l i c boolean userequals ( User user, Object o b j e c t ) { 3 r e t u r n u s e r. e q u a l s ( o b j e c t ) ; 4 } 5 6 p u b l i c Set<Thread> getthreadsforuser ( User u s e r ) { 7 r e t u r n u s e r. getthreads ( ) ; 8 } 9 10 p u b l i c S t r i n g getnameforuser ( User u s e r ) { 11 r e t u r n u s e r. getname ( ) ; 12 } 13 } 90

103 10.4. EJB-Assertion-Fassade Die EJB-Assertion-Fassade realisiert die Attributsprüfungen für Entitäten der Gargoyle-Anwendung. Sie werden für die Auswertung von Testfällen benötigt. Die Fassade kombiniert Methoden der EJB-Fassade und der Entity-Fassade, um die Attribute einer Entität mit den beim Methodenaufruf übergebenen Referenzwerten zu vergleichen. Im Gegensatz zur Entity-Fassade verwendet die EJB-Assertion-Fassade keine Typen des Domänenmodells in den Signaturen ihrer Fassadenmethoden, wodurch alle Details des zu testenden System vor der Testausführungsschicht verborgen werden. Auch die Fassadenklassen der EJB-Assertion-Fassade leiten von der abstrakten Fassade des Test-Basismodells ab. Auf eine Darstellung der Klassen wird an dieser Stelle verzichtet. Die relevanten Typen der EJB-Assertion-Fassade sind in Abbildung zu sehen. Die Abbildung demonstriert auÿerdem die Spezialisierungen der einzelnen Fassadentypen. Für die Fassadenparameter wird die Typklassikation der EJB-Fassade aus Abschnitt wiederverwendet (PrimaryKeyParameter, ForeignKeyParameter und ValueParameter). EntityFacade EJBFacadeMethod 1 - entityfacade 1 - getentitymethod Entity-Fassadenmodell EJB-Fassadenmodell * * EJBAssertionFacadeMethod AttributeAssertionMethod - mappedentity * 1 Entity EJB-Assertion-Fassadenmodell Entity-Modell EJBAssertionFacadeParameter ForeignKeyParameter * - mappedfk ForeignKey 1 PrimaryKeyParameter * - mappedpk 1 Attribute ValueParameter * - mappedvalueattribute 1 1 EJBAssertionFacadeType EntityAttributeType * - mappedattribute Abb : EJB-Assertion-Fassade und Mappings auf Meta-Modelle (Auszug) Die äuÿere Schittstelle der EJB-Assertion-Fassade enthält nur Parameter für Referenzwerte, die in den Methoden mit den aus dem Domänenmodell abzurufenden Attributwerten verglichen werden. Aus diesem Grund wird für Parameter nur die spezialisierende Klasse EntityAttributeType als Ableitung der EJBAssertionFacadeType-Klasse verwendet. Sie repräsentiert den Typ des über mappedattribute referenzierten Attributs einer Entität des Entity-Modells. 91

104 Der momentane Entwicklungsstand des Gargoyle-Test-Generator-Prototyps unterstützt nur eine Auswahl an Prüfungen; und zwar den Vergleich von Referenzwerten mit den Attributwerten einer Entität des Domänenmodells und Prüfungen auf die Existenz bzw. Nicht-Existenz einer Entität im Informationssystem. Die Fassadenmethode, die die Attributsprüfung für eine Entität implementiert, hat den Methodentypen AttributeAssertionMethod (siehe Abbildung 10.11). Um die Attributsprüfung zu realisieren und auf die Entitäten sowie deren Attributwerte zugreifen zu können, benötigt die Methode Referenzen zur EJB-Fassadenmethode und zur Entity-Fassade. Diese Mappings sind im oberen Teil der Abbildung zu sehen. Abb : EJB-Assertion-Fassade des Forensystems (Auszug) Die Prüfung der Existenz bzw. Nicht-Existenz einer Entität wird durch die Methodentypen ExistsAssertionMethod bzw. NotExistsAssertionMethod implementiert. Diese Methoden dienen zur Prüfung, ob Create-, Update- und Delete- Methodenaufrufe erfolgreich waren. Sie prüfen nach dem Methodenaufruf, ob eine bestimmte Entität im bzw. nicht im Informationssystem aundbar ist. Die Abbildung und Quelltextauszug 10.3 demonstrieren die Codegenerierung für die AttributeAssertion-Methoden an einem Beispiel. Das EJB-Assertion-Fassadenmodell in der Abbildung zeigt die Fassadenmethode assertattributesforpoll mit ihren Parametern. Diese entsprechen den Primärschlüsseln, Fremdschlüsseln und Wertattributen der zu prüfenden Entität. Im unteren Teil ist die Methodenkonguration abgebildet. Dort sind die Entity-Fassade und die EJB-Fassadenmethode aufgeführt, die den Zugri auf die Entität und deren Attribute beschreiben. 92

105 Der Quellcode der AttributeAssertion-Methoden wird anhand dieser Informationen generiert. Dazu wird die Entität über die kongurierte EJB-Fassadenmethode und die Fremd- und Primärschlüsselattribute aufgelöst. Der entsprechende Methodenaufruf ist in Quelltext 10.3 in den Zeilen 4 und 5 zu sehen. Die anschlieÿenden Anweisungen der Zeilen 6 bis 17 rufen die einzelnen Attributwerte der Entität über die Poll-Entity-Fassade ab und vergleichen diese über entsprechende JUnit-Prüfungen mit den Referenzwerten. Diese werden als Parameter an die Fassadenmethode übergeben (siehe Zeilen 1 und 2). Quelltext 10.3: Prüfmethode der EJB-Assertion-Fassade des Forensystems 1 p u b l i c void a s s e r t A t t r i b u t e s F o r P o l l ( S t r i n g f k _ t i t l e, i n t pk_threadid, 2 S t r i n g question, S t r i n g options, S t r i n g t h r e a d T i t l e, boolean l o c k e d ) 3 { 4 P o l l _poll = 5 _ejbforumfacade. getpollbythreadidandtitle ( pk_threadid, f k _ t i t l e ) ; 6 Assert. a s s e r t E q u a l s ( " Attribute threadid has unexpected value!", 7 pk_threadid, _ entitypollfacade. getthreadidforpoll ( _ poll ) ) ; 8 Assert. a s s e r t E q u a l s ( " Attribute title has unexpected value!", 9 f k _ t i t l e, _entitypollfacade. g e t T i t l e F o r P o l l ( _poll ) ) ; 10 Assert. a s s e r t E q u a l s ( " Attribute question has unexpected value!", 11 question, _entitypollfacade. getquestionforpoll ( _poll ) ) ; 12 Assert. a s s e r t E q u a l s ( " Attribute options has unexpected value!", 13 options, _entitypollfacade. getoptionsforpoll ( _poll ) ) ; 14 Assert. a s s e r t E q u a l s ( " Attribute threadtitle has unexpected value!", 15 t h r e a d T i t l e, _entitypollfacade. g e t T h r e a d T i t l e F o r P o l l ( _poll ) ) ; 16 Assert. a s s e r t E q u a l s ( " Attribute locked has unexpected value!", 17 locked, _ entitypollfacade. getlockedforpoll ( _ poll ) ) ; 18 } 93

106

107 11. Testfallgenerierung Inhalt 11.1 Testkonguration im Test-Generatormodell Testgenerierung Testmuster zur Testfallgenerierung Mit Hilfe der bereits vorgestellten Komponenten des Gargoyle-Test-Generators ist es möglich, Tests manuell zu spezizieren und alle zur Testausführung benötigten Komponenten zu generieren. Dieses Kapitel schlieÿt die Lücke zwischen Test-Fassaden und Test-Modell. Es stellt die modellgetriebene Erzeugung von Testfällen vor. Die Testfallgenerierung wird in zwei Stufen durchgeführt. Zuerst wird ein Test- Generatormodell erstellt, das Kongurationsinformationen für die anschlieÿende Erzeugung von Testfällen bereitstellt. Bei der anschlieÿenden Testgenerierung werden Testfälle im Test-Modell angelegt. Während dieser Modelltransformation werden die kongurierten Testmuster angewandt. Die Abbildung 11.1 zeigt den Ausschnitt des Workows des Gargoyle-Test- Generators, der die Testgenerierung realisiert. Er verfeinert den Bereich (b) des verallgemeinerten Workows aus Abbildung 8.1 auf Seite 64. Das Test- Generatormodell wird dabei per Modelltransformation aus dem EJB-Fassadenmodell initialisiert, da dieses die zu testenden Methoden der Gargoyle-Anwendungsfassade beschreibt. Hierbei werden Standardtestkongurationen für alle Methoden der EJB-Fassade generiert. Im zweiten Modelltransformationsschritt werden die Testmuster anhand der Konguration des Test-Generatormodells angewandt und die kongurierten Testfälle im Test-Modell erzeugt. Test-Fassadenmodelle «model» EJBFacadeModel «model» TestGeneratorModel Test-Modelle «model» TestModel Model-To-Model Transformation Model-To-Text Transformation Test-Muster Abb : Workow zur Testerzeugung 95

108 Der nachfolgende Abschnitt 11.1 beschreibt die Details des Test-Generatormodells. Dabei werden die einzelnen Modellstrukturen zur Konguration von Methodentests und der darauf anwendbaren Testmuster eingeführt. Im daran anschlieÿenden Abschnitt 11.2 wird die grundlegende Modelltransformation zur Testgenerierung vorgestellt. Im Abschnitt 11.3 werden abschlieÿend spezische Details der Testgenerierung für ausgewählte Testmuster beschrieben Testkonguration im Test-Generatormodell Das Test-Generatormodell beschreibt die Konguration für die Testgenerierung. Diese wird per Modelltransformation aus dem EJB-Fassadenmodell erzeugt. Dazu werden für die verschiedenen Methodentypen der EJB-Fassade Methodentests konguriert, die alle nötigen Informationen zur anschlieÿenden Testgenerierung bereitstellen Verwaltung von Test-Kongurationen Das Test-Generatormodell ordnet die Testkongurationen nach den Typen der EJB-Fassadenmethoden und den ihnen zugeordneten Entitäten (siehe Abbildung 10.6). Die dazu verwendete Struktur ist in Abbildung 11.2 zu sehen. Die TestGeneratorModelRoot-Klasse repräsentiert den Wurzelknoten des Modells. Sie speichert den Paketnamen und einen Namen für das zu testende System. Anschlieÿend wird für jede von der EJB-Fassade referenzierten Entität eine Instanz der Klasse TestConguration generiert. Diese repräsentiert eine Testsuite im Test-Modell, die die für eine Entität spezizierten Testfälle enthält. Für jeden Methodentypen der EJB-Fassade wird ein Methodentest (Klasse MethodTest) deniert. Er beschreibt die für diesen Methodentypen anwendbaren Testmuster (Klasse TestType). Weitere Informationen zu den Methodentests und den dazugehörigen Testmustern geben die Abschnitte und TestGeneratorModelRoot testpackagename : String systemundertest : String 1 - testgeneratormodelroot * - testconfigurations TestConfiguration - testsuite - methodtests MethodTest - methodtest- testpatterns TestPattern objectundertestname : String 1 * 1 * Abb : Kongurationsstruktur im Test-Generatormodell 96

109 Abbildung 11.3 zeigt einen Ausschnitt des aus dem EJB-Fassadenmodell generierten Test-Generatormodells des Forensystems. Für jede der sechs Entitäten des Forensystems wurde eine Testkonguration erzeugt, die eine Menge von Methodentests enthält. Abb : Testkongurationen im Test-Generatormodell Klassikation von Methodentests Methodentests beschreiben die Menge der anwendbaren Testmuster für eine Fassadenmethode. Die zu testende Fassadenmethode wird durch die Klasse MethodUnderTest beschrieben, welche auf die entsprechende Fassadenmethode verweist. Der obere Teil der Abbildung 11.4 zeigt den Zusammenhang zwischen MethodTest, MethodUnderTest und der abstrakten Fassadenmethode des Test- Basismodells. Da die Testgenerierung für die Methoden der EJB-Anwendungsfassade erfolgen soll, wird auf entsprechende Methoden der EJB-Fassade verwiesen. Diese wurden bei der Generierung der EJB-Fassade in sieben verschiedene Methodenklassen eingeteilt (siehe Abschnitt auf Seite 86). Dabei handelt es sich um die Methodenklassen CreateMethod, GetEntityMethod, UpdateMethod, Delete- Method, GetAllMethod, AssignMethod und UnassignMethod. Für jede dieser Methodentypen sind unterschiedliche Testmuster anwendbar. Eine Analyse der Anwendbarkeit von ausgewählten Testmustern wurde bereits bei der Evaluierung des Testprototypen im Abschnitt 6.1 auf Seite 45 durchgeführt. Die Unterteilung in verschiedene Methodentypen wird bei der Beschreibung von Methodentests erneut durchgeführt. Abbildung 11.4 zeigt die Klassikation von Methodentests im Test-Generatormodell. Diese ist nötig, da sich die Konguration eines Testmusters abhängig vom Typ der zu testenden Methode unterscheiden kann. 97

110 MethodTest - methodtest - methodundertest MethodUnderTest - facademethod FacadeMethod 1 1 * 1 name : String CreateMethodTests UpdateMethodTests DeleteMethodTests GetAllMethodTests GetEntityMethodTests AssignMethodTests UnassignMethodTests Abb : Klassikation von Methodentests Ein Beispiel für die Konguration von Methodentests für die Entität Post ist in Abbildung 11.5 dargestellt. Die Testkonguration enthält Methodentests vom Typ CreateMethodTest und DeleteMethodTest. Jeder der Methodentests ist über das enthaltene Method Under Test-Element einer Fassadenmethode zugeordnet. Der abgebildete CreateMethodTest beschreibt dabei die Konguration der Tests für die createpost-methode der EJB-Fassade, die im unteren Teil der Abbildung zu sehen ist. Abb : Klassikation von Methodentests und Testtypen Klassikation von Testmustern Den eingeführten Typen von Methodentests können nun einzelne Testmuster zugeordnet werden. Diese werden, wie in Abbildung 11.2 beschrieben, durch die Klasse TestPattern repräsentiert. Sie beschreiben die jeweilige Konguration 98

111 für die in der Prototypingphase identizierten Testmuster. Abbildung 11.6 zeigt die verschiedenen Typen von Testmustern. AttributeTest und AssociationTest repräsentieren mögliche Testmuster für die in Kapitel 6 beschriebenen Positiv- Tests. DuplicationTest, NotNullTest und NotFoundTest repräsentieren die beschriebenen Fehlertests. Das Testmuster NotExistsTest bezeichnet einen Testtypen, bei dem nach dem Aufruf einer Delete-Methode geprüft wird, ob die entsprechende Entität korrekt gelöscht wurde. TestPattern AttributeTest AssociationTest DuplicationTest NotNullTest NotFoundTest NotExistsTest Abb : Klassikation von Testmustern Wie bereits in der Prototypingphase beschrieben, stellen die aufgeführten Testmuster nur eine Auswahl dar. Bei Bedarf können weitere Testmuster deniert werden. Die hier vorgestellte Klassizierung gibt einen ersten Überblick über die verfügbaren Testmuster. Eine nähere Betrachtung von ausgewählten Testmustern erfolgt im dritten Teil dieses Kapitels, der die Testgenerierung für ausgewählte Testmuster beschreibt Kombination von Methodentests und Testmustern Anhand des Klassendiagramms in Abbildung 11.2 ist erkennbar, dass Methodentests und Testmuster beliebig miteinander kombiniert werden können. Dies ist nicht in allen Fällen sinnvoll. Beispielsweise ist es nicht zielführend, einen Create- MethodTest mit einer NotExistsTest-Konguration zu kombinieren; nach dem erfolgreichen Erzeugen einer Entität schlägt ein NotExistsTest immer fehl. Um solche sinnlosen Kombinationen zu verhindern, wäre es möglich, die jeweiligen Methodentests über Assoziationen mit den erlaubten Testmustern zu verbinden. Dies würde allerdings zu einer Vielzahl von Assoziationen zwischen den einzelnen Methodentests und den Testmustern führen, die zu unnötiger Komplexität bei den Heuristiken zur Generierung der Testkongurationen und der anschlieÿenden Testfallgenerierung führt. Aus diesem Grund wurde auf die As- 99

112 soziation von Methodentests mit den für sie erlaubten Testmustern verzichtet. Da die Testerzeugung aus dem Test-Generatormodell automatisiert durchgeführt wird, ist es einfach, nur die sinnvollen Testmuster eines Methodentests zur Testfallgenerierung zu verwenden. Ungewollte Kombinationen können über entsprechende Xtend-Checks verhindert Verwaltung von Methodenabhängigkeiten Während der Prototypingphase wurde festgestellt, dass für die meisten Testfälle ein geeignetes In-line Setup ausgeführt werden muss, um die zur Ausführung des Testfalls benötigten Entitäten des Domänenmodells bereitzustellen (siehe Abschnitt auf Seite 40). Um beispielsweise die Methode createpost testen zu können, müssen entsprechende Entitäten des Typs Forum und Thread vorhanden sein. Dies ist notwendig, da Kompositionsbeziehungen zwischen Forum, Thread und Post bestehen (siehe Abbildung 5.1 auf Seite 36). Folglich hängt die Methode createpost von der Methode createthread ab; diese wiederum hängt von der Methode createforum ab. Auÿerdem muss sichergestellt werden, dass die drei Entitäten korrekt miteinander assoziiert werden. Dazu werden Mappings zwischen den äquivalenten Primär- bzw. Fremdschlüsselparametern für die Methodenaufrufe benötigt. Im Abschnitt wurden die Methoden und Parameter der EJB-Fassade klassiziert. Die dort eingeführten Methodentypen und Mappings auf das Entity- Modell sowie die Klassikation von Primär- und Fremdschlüsselparametern werden bei der Erzeugung des Test-Generatormodells verwendet, um die beschriebenen Abhängigkeiten zwischen Methoden und Parametern zu bestimmen. - dependency TestGeneratorModelRoot testpackagename : String systemundertest : String 1 * - methoddependencies 0..1 * FacadeMethodDependency 1 * * - parametermapping SemanticEquivalentParameterMapping * * 1 - from 1 - to FacadeParameter Test-Basismodell * - parameters 1 - method FacadeMethod name : String - facademethod 1 Abb : Verwaltung vom Methodenabhängigkeiten für Tests 100

113 Zur Spezikation der Methodenabhängigkeiten wird die Struktur aus Abbildung 11.7 genutzt. Mit Hilfe der Klasse FacadeMethodDependency können Abhängigkeiten zwischen Fassadenmethoden speziziert werden. Dabei wird ein Mapping zwischen der über facademethod assoziierten Fassadenmethode und der Fassadenmethode der über dependency assoziierten FacadeMethodDependency beschrieben. Parameter der beiden Methoden, die semantisch äquivalent sind, werden über die Klasse SemanticEquivalentParameterMapping einander zugeordnet. Die Parametermappings werden für die Fremdschlüsselparameter der Fassadenmethode erzeugt. Für diese gibt es äquivalente Fremd- oder Primärschlüsselparameter in der über dependency verknüpften Methode. Über Facade- MethodDependency beschriebene Abhängigkeiten werden ausschlieÿlich für die Generierung des In-Line Setups von Testfällen verwendet. Aus diesem Grund werden sie nur für Create-Methoden erzeugt. Abbildung 11.8 zeigt einen Auszug der beschriebenen Methodenabhängigkeiten für das Test-Generatormodell des Forensystems. An der Markierung ist die Facade Method Dependency für die createpost-methode abgebildet. Das Mapping verweist auf die Methode createthread. Diese Abhängigkeit leitet sich aus dem Entity-Modell ab, da die Entität Thread Vaterelement einer Kompositionsbeziehung zur Entität Post ist. Unterhalb der createpost-methode benden sich zwei Semantic Equivalent Parameter Mappings. Sie verknüpfen die Fremdschlüsselparameter threadid und title mit den äquivalenten Parametern der createthread-methode. Im unteren Teil der Abbildung sind die Fassadenmethodenabhängigkeiten für die Methoden createuser und createforum zu sehen. Sie selbst sind nicht von anderen Methoden abhängig, da sie Create-Methoden für die Top-Level-Entitäten des Domänenmodells repräsentieren. Allerdings dienen sie als Ziele für die Mappings der anderen Methoden. Abb : Methodenabhängigkeiten im Test-Generatormodell 101

114 Neben den Methodenabhängigkeiten für das In-Line Setup der Testfälle gibt es noch weitere Mappings zwischen Methoden im Test-Generatormodell. Zum Beispiel muss ein Mapping zwischen der Method Under Test und der für diese Methode benötigten Create-Methode konguriert werden. Das Mapping ist in Abbildung 11.9 dargestellt. TestGeneratorModelRoot testpackagename : String systemundertest : String 1 * - methoddependencies - methoddependency FacadeMethodDependency 0..1 * MethodUnderTest * - dependencyparametermapping 1 * SemanticEquivalentParameterMapping * * 1 - from 1 - to FacadeParameter Test-Basismodell - facademethod 1 * - parameters 1 - method FacadeMethod name : String Abb : Zusätzliche Methodenabhängigkeit für MethodUnderTest Zusammenfassung Abschlieÿend werden die einzelnen Konzepte des Test-Generatormodells in einem Beispiel zusammengefasst. In der Abbildung ist das nale Test- Generatormodell des Forensystems dargestellt. Es deniert die einzelnen Testkongurationen für die Entitäten des Forensystems mit den verschiedenen Methodentests, den zugehörigen Testtypen und der Method Under Test. Unterhalb der Testkongurationen sind die Facade Method Dependencies abgebildet. Im unteren Teil der Abbildung sind die importierten Test-Fassaden zu erkennen, die bei der Modelltransformation von der EJB-Fassade ins Test-Generatormodell importiert wurden. Sie stellen die Fassadenmethoden für die einzelnen Testmethoden und Methodenabhängigkeiten bereit. 102

115 Abb : Finales Test-Generatormodell des Forensystems Testgenerierung Nachdem im ersten Teil dieses Kapitels das Test-Generatormodell beschrieben wurde, befasst sich dieser Abschnitt mit der Testgenerierung. Im Folgenden werden alle Komponenten der Modelltransformation zwischen dem Test-Generatormodell und dem Test-Modell vorgestellt, die nicht die Method Under Test und eventuell nachfolgende Prüfschritte betreen. Deren Generierung wird im Abschnitt 11.3 beschrieben, da sie von der Anwendung spezischer Testmuster abhängig sind. Die Struktur des Test-Modells wurde bereits im Kapitel 9 beschrieben, daher wird an dieser Stelle weitestgehend auf eine erneute Abbildung der generierten Test-Modellinstanzen verzichtet. An geeigneter Stelle werden Verweise auf die entsprechenden Abschnitte des Kapitels 9 angegeben. 103

116 Die hier beschriebene Modelltransformation zwischen Test-Generatormodell und Test-Modell lässt sich in die folgenden Schritte gliedern: Generierung von Testsuiten, Tests und Testschnittstellen Generierung von Testfällen und dazugehörigen Standardwerten Generierung des In-Line Setups der einzelnen Testmethoden Alle dazu benötigten Informationen sind im Test-Generatormodell gespeichert oder können über Heuristiken generiert werden. Rückgrie auf die Fassaden, das EJB-Modell oder das Enity-Modell sind nicht erforderlich Generierung der Testsuiten, Tests und Testschnittstellen Die Beschreibung der Generierung der Testsuiten, Tests und Testschnittstellen wird zusammengefasst, da die einzelnen Generierungsschritte auf die gleichen Informationen des Test-Generatormodells zurückgreifen. Bei Start der Modelltransformation wird eine Instanz der TestModelRoot-Klasse erzeugt. Sie bildet den Wurzelknoten des Test-Modells und übernimmt den Paketnamen und den Namen für das zu testende System aus den Daten der TestGeneratorModelRoot- Instanz. Anschlieÿend wird für jede TestConguration-Instanz eine entsprechende TestSuite erzeugt. Sie wird nach dem objectundertestname der TestCon- guration benannt. Innerhalb der Testsuite werden einzelne Tests (Test) und die dazugehörige Testschnittstelle (TestInterface) erzeugt. Dazu werden die in einer TestConguration enthaltenen MethodTest-Instanzen und die dazugehörigen TestType-Instanzen verwendet. Den jeweiligen Testschnittstellen werden Parameter (TestParameter) hinzugefügt. Dazu werden die Parameter der Method Under Test des Methodentests verwendet und entsprechend benannte Testparameter erzeugt. Diese verwenden die Typen der Fassadenparameter und referenzieren deren Facade- Type-Instanzen. Dies lässt sich am besten an einem Beispiel demonstrieren. Für die in Abbildung 11.5 auf Seite 98 dargestellte Testkonguration für das Object Under Test Post wird eine TestSuite Post mit drei Tests erzeugt: 1. Für den CreateMethodTest mit der Method Under Test createpost wird in Kombination mit dem Testtypen AttributeTest ein Test mit der Testschnittstelle testattributespostcreate und den Attributen der Method Under Test erzeugt. 2. Für den CreateMethodTest mit der Method Under Test createpost wird in Kombination mit dem Testtypen DuplicationTest ein Test mit der Testschnittstelle testduplicationpostcreate und den Attributen der Method Under Test erzeugt. 104

117 3. Für den DeleteMethodTest mit der Method Under Test deletepost wird in Kombination mit dem Testtypen NotExistsTest ein Test mit der Testschnittstelle testnotexistspostdelete und den Attributen der Method Under Test erzeugt Generierung der Testfälle und Standardwerte Für jeden Test wird eine Testinstanz (TestInstance) erzeugt, die einen Testfall speziziert. Eine Testinstanz wird nach der Testschnittstelle benannt. Dabei wird zusätzlich ein Index an den Namen angehängt, um mögliche Namenskonikte bei der späteren Generierung des Testcodes aus dem Test-Modell zu vermeiden. Der Testinstanz werden anschlieÿend Parameterinstanzen hinzugefügt, die die Testdaten des Testfalls repräsentieren. Eine Parameterinstanz wird für jeden Parameter der Testschnittstelle erzeugt. Dabei werden der Name und der Typ des Testparameters übernommen. Einer generierten Testinstanz wird bei der Modelltransformation ein Standardwert, abhängig vom Typen des Parameters, zugeordnet. Dazu wird eine erste grobe Heuristik verwendet: Zeichenketten wird dabei der Name des Parameters als Wert zugewiesen, booleschen Parametern der Wert false, ganzzahligen Parametern der Wert 1. Die Heuristik ist bei Bedarf erweiterbar, um aussagekräftigere Standardwerte zu erzeugen. Parameterinstanzen werden bei der Generierung mit dem entsprechenden Testparameter der Testschnittstelle assoziiert. Dadurch wird ein Mapping zwischen Testdaten und Testschnittstelle hergestellt. Bei der Testgenerierung wird für die Erzeugung der Testparameter der Typ DefaultParameterInstance verwendet. Bevor eine Parameterinstanz für die entsprechende DefaultParameterInstance angelegt werden kann, muss ein Default- ParameterContainer für die Testsuite und darin die DefaultParameterInstance erzeugt werden. Dieses Problem ist bei der verwendeten Modelltransformationssprache Xtend sehr einfach lösbar, da diese Funktionen zur Vermeidung von Duplikaten bereitstellt. Somit ist es möglich, DefaultParameterContainer und DefaultParameterInstances jedes Mal zu erzeugen, wenn sie benötigt werden. Sollte eine solches Element schon im Test-Modell existieren, wird es wiederverwendet. Ein Beispiel für eine generierte Testinstanz ist in Abbildung 9.11 auf Seite 77 dargestellt Generierung des In-Line Setups Die bisher vorgestellten Konzepte decken die Generierung von Tests bis zur Denition der Testmethode ab. An dieser Stelle wird die Generierung von Testschritten innerhalb der Testmethode beschrieben. Dieser Abschnitt stellt die Generierung von Testschritten und lokalen Variablen vor. Dazu werden zuerst die für die Testausführung nötigen Testschritte des In-Line Setups und die dafür benötigten lokalen Variablen erzeugt. 105

118 Bei der Modelltransformation zwischen Test-Generatormodell und Test-Modell werden, rekursiv mit Hilfe der Methodenabhängigkeiten, Methodenaufrufe generiert. Dabei wird, ausgehend von der Method Under Test und dann den Methoden der denierten Abhängigkeiten folgend, für jede Abhängigkeit ein Methodenaufruf als Testschritt erzeugt. Durch das rekursive Vorgehen entstehen die Testschritte mit den Methodenaufrufen für das In-Line-Setup in der richtigen Reihenfolge; von der Create-Methode der entsprechenden Top-Level-Entität des Domänenmodells bis hin zur Create-Methode der Entität, von der die Method Under Test abhängt. Für die Parameter der Fassadenmethoden werden lokale Variablen im Test- Modell erzeugt. Für Parameter, die per SemanticEquivalentParameterMapping miteinander verknüpft sind, wird bei der Generierung des Testfalls jeweils die gleiche lokale Variable verwendet. Dadurch wird sichergestellt, dass voneinander abhängige Methodenaufrufe die gleichen Fremd- bzw. Primärschlüsselparameter verwenden. Dabei wird eine lokale Variable nach dem Parameter einer Fassadenmethode benannt, für den kein weiteres Mapping auf andere Fassadenmethoden deniert ist. Das trit genau dann zu, wenn ein Parameter einen Primärschlüsselparameter einer Methode beschreibt. Die Abbildung demonstriert die aus den Mappings generierten Methodenaufrufe und Mappings für das In-Line Setup im Test-Modell. Vor der createpost- Methode, die die Method Under Test repräsentiert, wurden zuerst Methodenaufrufe für die Abhängigkeiten in Form der Methoden createforum und createthread generiert. Im unteren Teil der Abbildung ist das Mapping zwischen der lokalen Variable _createforum_title und dem Parameter title der Methode createpost markiert. Die gleiche lokale Variable wird auch im Mapping auf den äquivalenten Fremdschlüsselparameter title der darüber abgebildeten Methode createthread (und auch beim Mapping dieser zur createforum-methode) verwendet. Abb : Generierte Methodenabhängigkeiten im Test-Modell 106

119 11.3. Testmuster zur Testfallgenerierung Dieser Abschnitt stellt die im Gargoyle-Test-Generator implementierten Testmuster und die dazugehörigen Modelltransformationsschritte vor. Mit diesen wird das Kapitel zur Testfallgenerierung vervollständigt, da sie die letzten benötigten Testschritte für die einzelnen Tests generieren AttributeTest für Create-Methoden Das erste implementierte Testmuster entspricht dem im Kapitel 6 beschriebenen Positivtest in Form eines Attribut-Tests für Create-Methoden. Die Method Under Test für dieses Testmuster ist die Create-Methode für eine der Entitäten des Domänenmodells. Zusätzlich muss eine Methode der EJB-Assertion- Fassade aufgerufen werden, die die Attributwerte der mit der Create-Methode erstellten Entität überprüft. Dazu verweist die AttributeTest-Klasse des Test- Generatormodells auf eine zusätzliche Fassadenmethode, die die zur Create- Methode passende AttributeAssertionMethod der EJB-Assertion-Fassade repräsentiert. Konguration im Test-Generatormodell Die AttributeTest-Konguration wird bei der Generierung des Test-Generatormodells aus der EJB-Fassade initialisiert. Dazu wird die EJB-Assertion-Fassade bei der Modelltransformation als zusätzliche Ressource geladen und bei der Generierung referenziert. Auch die AttributeAssertionMethod muss im Test- Generatormodell entsprechende Parametermappings kongurieren, damit die für den Aufruf der Method Under Test verwendeten Parameter auch für den Aufruf der Prüfmethode wiederverwendet werden können. Dieses Mapping wird erneut über die SemanticEquivalentParameterMapping-Klasse beschrieben. Die Kongurationsstruktur für das AttributeTest-Muster ist in Abbildung dargestellt. Die Referenz auf die AttributeAssertionMethod wird dabei durch die Assoziation assertionmethod beschrieben, die Referenz auf die Method Under Test über die Assoziation methodtest.methodundertest. Das Parametermapping zwischen diesen Methoden wird über die Assoziation assertiontomutparametermapping deniert. Testfallgenerierung für Attribut-Test der Create-Methode Die Generierung der letzten Testschritte für den Attribut-Test geschieht analog zu den bereits generierten Testschritten des In-Line Setups. Die Parameter der 107

120 MethodTest - methodtest - methodundertest MethodUnderTest - facademethod 1 1 * 1 - methodtest SemanticEquivalentParameterMapping * - testpatterns TestPattern * * * 1 - from 1 - to FacadeParameter AttributeTest Test-Basismodell * - parameters * 1 - assertiontomutparametermapping - assertionmethod 1 - method 1 FacadeMethod 1 name : String Abb : Konguration für AttributeTest Method Under Test werden auf die entsprechenden lokalen Variablen gemappt und ein Testschritt für den Aufruf der Fassadenmethode erzeugt. Danach werden die Parameter der Methode zur Attributsprüfung den lokalen Variablen zugeordnet und der dazugehörige Testschritt im Test-Modell angelegt. Nach Abschluss der Testschrittgenerierung müssen noch die Parameter der Testschnittstelle auf die entsprechenden lokalen Variablen abgebildet werden. Dazu werden entsprechende LocalVariableToTestInterfaceMapping-Testschritte erzeugt. Abb : Testfall für AttributeTest im Test-Modell 108

121 Abbildung zeigt den aus dem Test-Generatormodell generierten Attribut- Test für die createpost-methode. Unterhalb der Attribut-Prüfmethode der EJB- Assertion-Fassade sind die Mappings zwischen lokalen Variablen und Fassadenparametern zu sehen. Der aus diesem Test generierte Quelltext ist im Anhang A.4 aufgelistet. Alternatives Testmuster für Update-Methoden Die in Abbildung beschriebene Modellstruktur kann auch zur Konguration von Attribut-Tests für andere Methodentypen verwendet werden. Zum Beispiel werden Attribut-Tests für Update-Methoden folgendermaÿen aufgebaut: Die Method Under Test referenziert die Update-Methode der EJB-Fassade, diese wiederum hat eine Abhängigkeit von der entsprechenden Create-Methode über das Abhängigkeitsmapping im Test-Generatormodell. Die AttributeAssertionMethod wird weiterhin verwendet. Für dieses Testmuster ändert sich allerdings das Mapping der Parameter zwischen den Methoden. Da eine Update-Methode zum Ändern der Attribute (und auch der Primär- und Fremdschlüsselattribute) verwendet werden kann, müssen andere Parameter zwischen der Update-Methode und der Create-Methode gemappt werden; auch das Mapping zwischen der Attribut-Prüfmethode und der Update-Methode unterscheidet sich vom momentan unterstützten Mapping. Die Heuristik für die Generierung dieser Mappings ist bisher nicht in der Modelltransformation zur Erzeugung des Test-Generatormodells implementiert DuplicationTest für Create-Methoden Das Duplikats-Testmuster für Create-Methoden wird über einen zweifachen Aufruf der Method Under Test realisiert. Dabei wird der zweite Methodenaufruf in einem ExpectedException-Testschritt gekapselt, um die Auslösung der erwarteten Ausnahme zu überprüfen. Die dazu benötigte Konguration des Testmusters ist in Abbildung dargestellt. Diese erfordert keine Mappings zwischen Methoden, da für den zweiten Aufruf der Method Under Test die Parameterkonguration des ersten Aufrufs wiederverwendet werden kann. MethodTest - methodtest 1 * - testpatterns TestPattern DuplicationTest Abb : Konguration für DuplicationTest 109

122 Bei der Erzeugung des Test-Generatormodells ist es ausreichend, ein DuplicationTest-Element für den CreateMethodTest zu erzeugen. Für die Testfallgenerierung wird analog zu den Schritten für den Attribut-Test vorgegangen. Zuerst wird ein Testschritt für die Method Under Test erzeugt und das Mapping der Methodenparameter auf die lokalen Variablen durchgeführt. Für den zweiten Testschritt wird ein ExpectedException-Testschritt für die zu erwartende Ausnahme erzeugt. Diesem wird anschlieÿend eine Kopie des Methodenaufrufs der Method Under Test zugewiesen. In Abbildung ist der aus dem Testmuster generierte Test zu sehen. Die Markierung zeigt den ExpectedException-Testschritt mit der erwarteten Fehlermeldung der ausgelösten Ausnahme und dem gekapselten Aufruf der create- Post-Methode. Der aus dem Test-Modell generierte Quelltext ist im Anhang A.5 abgebildet. Abb : Testfall für DuplicationTest im Test-Modell Alternative Anwendung des Testmusters Das Duplikats-Testmuster kann auch für Update-Methoden angewendet werden. Dies ist aber weitaus komplizierter als im vorliegenden Fall der Create- Methoden. Über das In-Line-Setup werden zwei Entitäten des gleichen Typs erzeugt. Anschlieÿend wird eine der Entitäten über die Update-Methode verändert. Dabei wird als neuer Primärschlüssel der Primärschlüssel der anderen Entität verwendet. Dies sollte zur Auslösung der erwarteten Ausnahme führen. Dieses Testmuster erfordert ebenfalls eine Implementierung weiterer Heuristiken für die Konguration und das Mapping von Methodenabhängigkeiten bei der Generierung des Test-Generatormodells. Auÿerdem müssten Änderungen an der Strukturierung der Methodenabhängigkeiten durchgeführt werden, um mehrfache Abhängigkeiten der Method Under Test zum In-Line Setup abbilden zu können. 110

123 NotExistsTest für Delete-Methoden Als letztes Testmuster wird das NotExistsTest-Muster für Delete-Methoden vorgestellt. Es ist dem AttributeTest-Muster ähnlich, da es ebenfalls eine Testschrittfolge deniert, die aus dem Aufruf der Method Under Test und einer Prüfmethode der EJB-Assertion-Fassade besteht. An der Kongurationsstruktur in Abbildung ist zu erkennen, dass die Konguration des Testmusters wie die des AttributeTest-Musters aufgebaut ist. In der Konguration wird ein Parametermapping zwischen einer Delete-Methode (Assoziation methodtest.methodundertest) und einer NotExistsAssertionMethod der EJB-Assertion-Fassade (Assoziation notexistsmethod) deniert. Ein Unterschied zwischen dem NotExistsTest-Muster und dem AttributeTest- Muster ist die Zusammensetzung der Parametermappings. Da Delete-Methoden und die NotExistsAssertion-Methoden der EJB-Assertion-Fassaden nur Fremdund Primärschlüsselparameter besitzen, beschränkt sich die Generierung der Parametermappings im Test-Generatormodell und die anschlieÿende Testfallgenerierung auf eine Teilmenge der für das AttributeTest-Muster benötigten Parameter. MethodTest - methodtest - methodundertest MethodUnderTest - facademethod 1 1 * 1 - methodtest SemanticEquivalentParameterMapping * - testpatterns TestPattern * * 1 - from * 1 - to FacadeParameter NotExistsTest * 1 - notexiststomutparametermapping Test-Basismodell * - parameters 1 - method 1 - notexistsmethod FacadeMethod 1 name : String Abb : Konguration für NotExistsTest Die Testfallgenerierung entspricht ebenfalls den Schritten der AttributeTest- Generierung. Zuerst wird ein Testschritt für die Method Under Test erzeugt und auf lokale Variablen gemappt. Dann wird der Testschritt für die Prüfmethode generiert und abschlieÿend das Mapping zwischen lokalen Variablen und der Testschnittstelle erzeugt. Der generierte Test im Test-Modell ist in Abbildung dargestellt. In der Testschrittfolge kann man unter anderem die Methodenabhängigkeit der Delete-Methode (deletepost) auf die Create-Methode der gleichen Entität (createpost) erkennen. Der aus dem Test-Modell generierte Testfall ist im Quelltext A.6 im Anhang abgebildet. 111

124 Abb : Testfall für NotExistsTest im Test-Modell Alternative Anwendung des Testmusters Auch das NotExistsTest-Muster kann potentiell für andere Methodentypen angewendet werden. Denkbar wäre zum Beispiel eine Verwendung bei Update- Tests. Beschreiben diese zum Beispiel das Updaten von Fremdschlüsselparametern also das bereits beim DuplicationTest-Muster beschriebene Verschieben einer Entitäten auf ein anderes Vaterelement kann der NotExistsTest zur Prüfung der korrekten Löschung der Entität aus der Kompositionsbeziehung des alten Vaterelements verwendet werden. 112

125 12. Gargoyle-Test-Generator Inhalt 12.1 Schichtenarchitektur Generator-Workow Gargoyle-Test-Generator im MDA-Kontext In den vorangegangenen Kapiteln wurden die einzelnen Konzepte und Methoden des Gargoyle-Test-Generators vorgestellt. Dabei wurde die Schichtenarchitektur der mit dem Generator erzeugten Testkomponenten schrittweise eingeführt und die für die Generierung verwendeten Meta-Modelle, Modelle, Modelltransformationen und Codegeneratoren vorgestellt. Abschlieÿend kann eine vollständige Betrachtung des Gargoyle-Test-Generators und der dadurch implementierten modellgetriebenen Methode für die Testgenerierung vorgenommen werden. Zu Beginn werden die in den vorangegangenen Kapiteln vorgestellten Sichten auf die Schichtenarchitektur zusammengeführt. Anschlieÿend wird die modellgetriebene Methode deniert. Zum Abschluss wird die Rolle der einzelnen Generatorkomponenten im Kontext der Model Driven Architecture betrachtet Schichtenarchitektur In Abbildung 12.1 ist die nale Schichtenarchitektur der Gargoyle-Tests zu sehen. Alle hervorgehobenen Komponenten werden durch den Gargoyle-Test- Generator erzeugt. Die Abstraktionsschicht versteckt die systemspezischen Details der zu testenden Gargoyle-Anwendung vor der Testschicht. Das Domänenmodell und die Anwendungsfassade werden dabei über die Entity-Fassade und die EJB-Fassade abstrahiert. Die EJB-Fassade bildet den Zugri auf die Methoden der Anwendungsfassade ab. Die Entity-Fassade kapselt die Zugrie auf das Domänenmodell. Die EJB-Assertion-Fassade stellt Prüfmethoden für die Testausführung bereit und nutzt dazu Funktionen der EJB- und der Entity-Fassade. Die Testschicht besteht aus dem Test-Servlet und dem Test-Wrapper. Das Test- Servlet läuft im Kontext des Application Servers und enthält die generierten 113

126 Browser Test-Wrapper (HtmlUnit) EJB Test-Servlet (JUnit) EJB-Assertion-Fassade Entity-Fassade EJB-Fassade Testschicht Abstraktionsschicht Entities Anwendungsfassade Controller DAO Gargoyle-Anwendung Application Server Datenbank Entity Manager Komponente Kontrollfluss Abb : Finale Schichtenarchitektur der Gargoyle-Tests Tests für die Gargoyle-Anwendung. Zur Ausführung der Testfälle greift das Test- Servlet auf die Test-Fassaden der Abstraktionsschicht zu. Es führt über die EJB- Fassade die einzelnen Testschritte auf der Gargoyle-Anwendungsfassade aus und nutzt Funktionen der EJB-Assertion-Fassade, um Prüfschritte für die durchgeführten Operationen auszuführen. Der Test-Wrapper stellt Funktionen bereit, die eine Ausführung der Tests im Test-Servlet und die anschlieÿende Auswertung der Testergebnisse durch Continuous Integration-Umgebungen ermöglicht. Alle Komponenten der Abstraktionsschicht und der Testschicht werden vollständig vom Gargoyle-Test-Generator erzeugt und sind ohne manuelle Anpassungen des generierten Quellcodes lauähig. 114

127 12.2. Generator-Workow Die Abbildung 12.2 zeigt den nalen Workow des Gargoyle-Test-Generators. Dieser setzt sich aus den bereits vorgestellten Teil-Workows aus den vorangegangen Kapiteln zum Test-Modell, den Test-Fassaden und der Testfallgenerierung zusammen. Die dunkelblauen Pfeile repräsentieren die Modelltransformationen, die hellblauen Pfeile beschreiben die Codegeneratorschritte. Auf der linken Seite ist der Workow des Gargoyle-Generators zu sehen. Die Modelle der Test-Fassaden werden aus den Gargoyle-Modellen der zu testenden Anwendung erzeugt. Das Test-Generatormodell wird aus dem EJB-Fassadenmodell erzeugt und bildet die Grundlage für die Erzeugung des Test-Modells. Auf der rechten Seite sind die generierten Quelltextartefakte abgebildet, die die Komponenten der Schichtenarchitektur repräsentieren. Gargoyle-Modelle Test-Fassadenmodelle Test-Modelle Quellcode «model» GeneratorModel «code» Domäne «code» Gargoyle-Komponenten «model» EntityModel «model» EntityFacadeModel «code» EntityFacade «code» EJBAssertionFacade «model» EJBGeneratorModel «model» EJBAssertionFacadeModel «code» EJBFacade «model» EJBModel «model» EJBFacadeModel «model» TestGeneratorModel «code» Tests «code» Test-Servlet Model-To-Model Transformation Model-To-Text Transformation «model» TestModel «code» Test-Wrapper Abb : Finaler Workow des Gargoyle-Test-Generators Die Komplettierung des Generator-Workows bedeutet auch, dass der Plan, eine vollständige Methode zum Generieren von Tests für Gargoyle-Anwendungen zu entwickeln, erfolgreich erfüllt werden konnte. 115

128 Daher kann, dem Ziel dieser Diplomarbeit entsprechend, eine Methode zum modellgetriebenen Testen EJB-basierter Informationssysteme deniert werden: 1. Erzeugen der Test-Fassaden 1. Generierung des EJB-Fassadenmodells aus dem EJB-Modell der Gargoyle-Anwendung 2. Generierung des Entity-Fassadenmodells aus dem Entity-Modell der Gargoyle-Anwendung 3. Generierung des EJB-Assertion-Fassadenmodells aus dem EJB- Fassadenmodell unter Nutzung des Entity-Fassadenmodells 4. Codegenerierung 1. Codegenerierung EJB-Fassade 2. Codegenerierung Entity-Fassade 3. Codegenerierung EJB-Assertion-Fassade 2. Erzeugen der Tests 1. Initialisierung des Test-Generatormodells aus dem EJB-Fassadenmodell unter Nutzung des EJB-Assertion-Fassadenmodells 2. Generierung des Test-Modells aus dem Test-Generatormodell 3. Codegenerierung 1. Codegenerierung Tests 2. Codegenerierung Test-Servlet 3. Codegenerierung Test-Wrapper Den beschriebenen Schritten folgend, werden alle zur Ausführung der Tests benötigten Komponenten erzeugt. Der denierte Workow erlaubt eine automatisierte Ausführung der Testgenerierung, zum Beispiel unter Benutzung der Modeling Workow Engine (MWE), die auf der Eclipse-Plattform verfügbar ist [Ecl12c]. 116

129 12.3. Gargoyle-Test-Generator im MDA-Kontext Zum Abschluss werden die einzelnen Modelle des Gargoyle-Test-Generators anhand ihrer Rolle im MDA-Kontext betrachtet. Sie werden zwischen plattformunabhängigen Modellen und plattformspezischen Modellen unterschieden. Die Modelle der Test-Fassaden das EJB-Fassadenmodell, das Entity-Fassadenmodell und das EJB-Assertion-Fassadenmodell sind plattformspezische Modelle. Sie verweisen direkt auf die Modelle des Gargoyle-Generators und sind somit nur für die Abstraktion der Gargoyle-spezischen Komponenten geeignet. Sowohl das Test-Generatormodell als auch das Test-Modell gehören zur Klasse der plattformunabhängigen Modelle. Sie stellen ausschlieÿlich abstrakte Konstrukte für die Testkonguration und Testbeschreibung zur Verfügung. Zur Anbindung von zu testenden Systemen wird die abstrakte Fassadenstruktur des Test-Basismodells aus Abschnitt verwendet. Das bedeutet, dass die implementierte Methode auch zur modellgetriebenen Testgenerierung anderer Anwendungen verwendet werden kann. Diese müssen über Fassaden abstrahiert werden, die die Struktur des Test-Basismodells implementieren. Abbildung 12.3 demonstriert eine mögliche Verwendung der Test-Generator- Komponenten für eine generische Anwendung. Der Einsatz kann dabei sowohl modellgetrieben als auch modellbasiert erfolgen. Dies ist an den gestrichelten Pfeilen für die Modelltransformationen und Codegenerierungsschritte erkennbar. Das Test-Generatormodell, das Test-Modell, die zwischen diesen Modellen implementierte Modelltransformation sowie die Codegeneratorkomponente für die Tests können für die Testgenerierung erneut verwendet werden. Anwendungs-Modelle Test-Fassadenmodelle Test-Modelle Quellcode «artifact» GenericFacade «artifact» GenericApplicationModel «artifact» GenericFacadeModel «model» TestGeneratorModel optional Model-To-Model Transformation Model-To-Model Transformation Model-To-Text Transformation «model» TestModel «code» Tests Abb : Möglicher alternativer Einsatz des Gargoyle-Test-Generators 117

130

131 Teil IV. Evaluierung und Zusammenfassung 119

132

133 13. Evaluierung Inhalt 13.1 Vorgehensweise Modellgetriebene Methode Anwendbarkeit Wartbarkeit In diesem Kapitel werden die Ergebnisse und der Verlauf dieser Diplomarbeit evaluiert. Dabei werden verschiedene Gesichtspunkte betrachtet. Zuerst wird in Abschnitt 13.1 auf die Vorgehensweise zurückgeblickt und die während der Entwicklungsphase des Gargoyle-Test-Generators getroenen Entscheidungen bewertet. Anschlieÿend wird im Abschnitt 13.2 auf die modellgetriebene Methode zur Testgenerierung eingegangen. Die Anwendbarkeit des in dieser Diplomarbeit vorgestellten Ansatzes wird in Abschnitt 13.3 anhand von Anwendungsbeispielen evaluiert. Abschlieÿend wird die Wartbarkeit des Gargoyle-Test-Generators in Abschnitt 13.4 mit Hilfe einer Fallstudie betrachtet. Zu Beginn der Diplomarbeit wurden verschiedene Ziele deniert. Es galt herauszunden, inwiefern die Spezikation von Tests für Informationssysteme möglich ist, wenn nur auf die statische Struktur des Domänenmodells und die Semantik der darauf ausgeführten Operationen zurückgegrien werden kann. Dazu passend sollte ein universell anwendbarer, modellgetriebener Ansatz zur Testgenerierung deniert werden. Diese Methode sollte anschlieÿend prototypisch implementiert werden. Im Laufe des Kapitels wird bei der Betrachtung der einzelnen Evaluierungsaspekte auf die Erfüllung dieser Ziele eingegangen Vorgehensweise Bei der Entwicklung des Gargoyle-Test-Generators wurde eine Prototypingphase mit anschlieÿender Implementierungsphase durchgeführt. Die Prototypingphase diente zur Präzisierung der Anforderungen sowie zur Evaluierung der Ableitbarkeit von Tests aus dem Domänenmodell und den Methoden des Informationssystems. Die während dieser Phase entwickelten Tests dienten als Referenzumgebung für den anschlieÿenden modellgetriebenen Generatoransatz. In der nachfolgenden Implementierungsphase wurde die modellgetriebene Methode de- niert und implementiert. 121

134 Der Rückgri auf einen Prototypen zur Evaluierung des weiteren Vorgehens und zum Konkretisieren von Anforderungen kann durchweg positiv bewertet werden. Dabei ist die frühe Verwendung des Forensystem-Beispiels aus Kapitel 3 hervorzuheben. Mit diesem konnten schon vor der Prototyperstellung Anwendungsbeispiele für Testfälle deniert werden. Diese wurden anschlieÿend evaluiert. Die bei der Prototypimplementierung gesammelten Erfahrungen und die implementierten Testfälle bildeten eine gute Grundlage zur Modellierung der abstrakten Strukturen zur Testfallbeschreibung sowie der Konguration der Testmuster. Dabei wäre es hilfreich gewesen, noch mehr unterschiedliche Testfälle im Prototypen zu implementieren. Dies hätte besonders im Bereich der Testmuster zu noch besseren Ergebnissen bei der Entwicklung des modellgetriebenen Ansatzes führen können. Rückblickend kann festgestellt werden, dass die Prototypingphase zu früh beendet wurde. Die Auswahl eines geeigneten Zeitpunktes zum Abbruch der Phase wurde allerdings durch den Umstand erschwert, dass der der Prototypanwendung zugrundeliegende Gargoyle-Generator noch nicht voll funktionsfähig war. Er wurde in einer parallel zu dieser Diplomarbeit verlaufenden Bachelorarbeit von Tristan Langer vervollständigt und weiterentwickelt [Lan12]. Dadurch waren einige der zu testenden Methoden erst während der Implementierungsphase verfügbar. Zu diesem Zeitpunkt war die Modellierung der Strukturen zur Beschreibung der Testmuster schon weit fortgeschritten. Andererseits hätte eine weitere Verzögerung des Beginns der Implementierungsphase zu zeitlichen Problemen bei der Fertigstellung des Gargoyle-Test-Genrators innerhalb der Diplomarbeitszeit geführt. Die Auswahl der Eclipse-Plattform mit dem Eclipse Modeling Framework sowie den Transformationssprachen Xtend und Xpand zur Modelltransformation und Codegenerierung hat sich bei der Entwicklung des Gargoyle-Test-Generators als richtig erwiesen. Während der Implementierung traten keine gravierenden technischen Probleme auf. Alle geplanten Funktionen konnten mit Hilfe der gewählten Technologien realisiert werden. Für die Durchführung der Implementierungsphase wurde eine Mischung aus Bottom-Up- und Top-Down-Ansatz gewählt. Zuerst wurde das Test-Modell und die Codegenerierung der Tests implementiert. Dies ermöglichte einen frühen Vergleich mit der Referenzumgebung aus der Prototypingphase und wirkte sich positiv auf die Qualität des generierten Quellcodes aus. Die generierten Tests konnten früh innerhalb der Continuous Integration-Umgebung getestet und validiert werden. Nachdem die Entwicklung des Test-Modells abgeschlossen war, wurde mit einem Top-Down-Ansatz fortgefahren, in dem die Modellierung und Generierung der Test-Fassaden aus den Gargoyle-Modellen implementiert wurde. Nach Abschluss dieses Schritts waren vollständige Tests der Umgebung möglich. Dazu wurden Tests manuell im Test-Modell unter Rückgri auf die Test-Fassaden speziziert und anschlieÿend validiert. 122

135 Im Anschluss wurde das Test-Generatormodell und die modellgetriebene Anwendung von Testmustern implementiert. Im Verlauf dieses Prozesses wurden die Test-Fassadenmodelle durch spezielle Methoden- und Parametertypen verfeinert. Diese stellen die zur Initialisierung des Test-Generatormodells benötigten Informationen bereit. Die Implementierung der Modelltransformationen zur Initialisierung des Test-Generatormodells und zur Generierung von Tests im Test-Modell wurde parallel durchgeführt. Im Verlauf der Entwicklung dieser Komponenten stellte sich heraus, dass einige der Testmuster nicht oder nur schwer über das Generatormodell kongurierbar waren. Dabei handelte es sich um Testmuster, die während der Prototypingphase aufgrund der fehlenden Funktionen des Gargoyle-Generators nicht evaluiert werden konnten. Aufgrund des nahenden Abschlusses der Diplomarbeit konnten entsprechende Anpassungen an den Meta-Modellen und Modelltransformationen nicht mehr durchgeführt werden. Auf die dazu nötigen Verbesserungen wird im Ausblick im Abschnitt 14.2 eingegangen. Gegen Ende der Implementierungsphase wurde für ausgewählte Testmuster ein Vergleich zwischen den generierten Tests und den zuvor manuell erstellten Tests durchgeführt. Es stellte sich heraus, dass der generierte Quellcode der Tests identisch war. Dadurch wurde gezeigt, dass die modellgetriebene Anwendung von Testmustern zur Testgenerierung funktioniert. Abschlieÿend kann ein erfolgreicher Abschluss der prototypischen Implementierung des Gargoyle-Test-Generators festgestellt werden. Der Generator erzeugt alle zur Durchführung von Tests benötigten Komponenten. Alle geplanten Funktionen wurden realisiert und eine vollständige Implementierung der modellgetriebenen Methode zur Testgenerierung erreicht. Damit wurden die zu Beginn der Diplomarbeit gestellten Ziele erreicht Modellgetriebene Methode Der geplante modellgetriebene Ansatz zum Testen von Informationssystemen konnte erfolgreich implementiert werden. Basierend auf dem Ansatz wurde im Verlauf der Diplomarbeit eine modellgetriebene Methode zur Testgenerierung deniert. Dabei sind besonders drei Punkte hervorzuheben: 1. Die vorgestellte modellgetriebene Methode ist universell anwendbar. Aufgrund der Abstraktion des System Under Test über die Test-Fassaden kann die Testgenerierung prinzipiell für beliebige Informationssysteme verwendet werden. Dazu muss das entsprechende System über eine Fassade an den Gargoyle-Test-Generator angebunden werden, die die abstrakte Fassadenstruktur des Test-Basismodells implementiert. Durch die konsequente Trennung der Tests von der zu testenden Anwendung innerhalb der Schichtenarchitektur benötigt die Testschicht keine Informationen über das der Anwendung zugrundeliegende Domänenmodell. 123

136 2. Zwischen den Meta-Modellen des Gargoyle-Test-Generators besteht eine strikte fachliche Trennung. Die Meta-Modelle der EJB-Fassade, der Entity-Fassade und der EJB-Assertion-Fassade abstrahieren das System Under Test. Das Test-Generator-Meta-Modell dient zur Konguration der Testgenerierung. Das Test-Meta-Modell beschreibt abstrakte Tests und deren Umgebung. 3. Alle Modelltransformationen des Generators sind automatisiert durchführbar. Nur die Namen der jeweiligen Eingabe- und Ausgabemodelle sowie ein symbolischer Name für das System Under Test werden zur Ausführung benötigt. Diese Informationen könnten zusätzlich über Heuristiken bestimmt werden. Damit ist der implementierte Generator vollständig MDA-konform Anwendbarkeit Der Gargoyle-Test-Generator wurde zum Abschluss der Implementierungsphase anhand von verschiedenen Anwendungsbeispielen evaluiert. Dabei wurden für zwei frühe Prototypen von Gargoyle-Anwendungen Tests generiert. Bei der ersten Anwendung handelt es sich um ein Wiki zur Dokumentation von Metriken [Sch12]. Die zweite Anwendung dient zur modellbasierten Integration von Referenzmodellen [PL11]. Auÿerdem wurde die Anbindung einer neuen Fassade an den Test-Generator durchgeführt. Die Fassade beschreibt web-basierte Systemtests am Beispiel des Forensystems [Kre12] Testgenerierung für Metric-Wiki Die Testgenerierung für das Metrik-Wiki konnte ohne Probleme durchgeführt werden. Dazu wurden neue Workows auf Basis der Eclipse Modeling Work- ow Engine (MWE) erzeugt, die entsprechende Eingabe- und Ausgabemodelle kongurieren und die jeweilige Modelltransformation ausführt. Die bestehenden MWE-Workows des Forensystems wurden dazu kopiert und angepasst. Mit den MWE-Workows konnten die Test-Fassaden, das Test-Generatormodell und das Test-Modell fehlerfrei erzeugt werden. Der aus den Modellen generierte Quellcode war vollständig und konnte ohne Nachbearbeitung kompiliert werden. Inklusive des anschlieÿenden Aufbaus von neuen Eclipse-Projekten für die Erzeugung der Container und das Deployment in den Application Server wurde für die Testgenerierung ca. eine Stunde benötigt. Dabei wurden 3255 LOC (Lines Of Code) an Test-Quellcode generiert. Bei der Ausführung der Tests in der Continuous Integration-Umgebung wurde auf Anhieb ein Fehler in der Anwendung festgestellt. Ein Testfall zum Attribut- Test einer Entität des Metrik-Wikis schlug mit folgender Fehlermeldung fehl: 124

137 Internal Exception: com.mysql.jdbc.exceptions.jdbc4.mysqlsyntaxerrorexception: You have an error in your SQL syntax near 'RANGE, RATING, SCALE, TYPE, UNIT, EOMC_ID, MEASUREDISCUSSION_ID, MEASUREINFO' at line 1 Ein Attributname war identisch mit dem Schlüsselwort range der MySQL- Syntax, sodass Operationen auf der Entität zu Fehlern beim Zugri auf die Persistenzschicht führten. Der Fehler konnte direkt behoben werden, indem dem Attribut ein neuer Name für die Persistierung zugeordnet wurde. Der Quelltextauszug 13.1 zeigt die notwendige Anpassung der Anwendung zum Beheben des Fehlers. name=" MeasureRange " ) 2 p r i v a t e S t r i n g range ; Quelltext 13.1: Fehlerbehebung für Entity-Attribut Testgenerierung für Reference Model Integration Für den zweiten Anwendungsfall konnte die Testgenerierung erfolgreich wiederholt werden. Für das Anlegen von MWE-Workows und die anschlieÿende Generierung wurden ca. 15 Minuten benötigt. Dabei wurden 9655 LOC für den Test- Quellcode erzeugt. Bei der Ausführung der Tests konnte erneut ein Fehler in der Anwendung gefunden werden. In diesem Fall handelte es sich um einen Testfall, der anhand des NotExistsTest-Musters für Delete-Methoden erzeugt wurde. Nach eingehender Analyse konnte eine fehlerhafte Implementierung des durch den Gargoyle-Generator generierten Quellcodes identiziert werden. Dies konnte auf einen Fehler der Codegeneratorkomponente des Gargoyle-Generators zurückgeführt werden. Dieser Fehler konnte auch bei den Tests für die Forensystem-Anwendung nachgestellt werden. Abbildung 13.1 zeigt die Ausgabe der manuellen Testausführung über das Test-Servlet. Abb : Fehler im Gargoyle-Generator in Delete-Methoden 125

138 Testmodellierung für Systemtests Mit der Integration der Systemtests für das Forensystem wurde die Abstraktion von Systemen über die Test-Fassaden evaluiert. Dazu wurde die Systemtest- Fassade aus der Bachelorarbeit von Michael Krein verwendet [Kre12]. Abbildung 13.2 zeigt einen Ausschnitt des Systemtest-Fassadenmodells für das Forensystem. Die Elemente vom Typ System Facade Method implementieren die abstrakte FacadeMethodType-Klasse des Test-Basismodells. In der Abbildung sind drei Fassadenmethoden erkennbar: createforum, createuser und addusertoforum. Auÿerdem wurden Fassadenmethoden vom Typ Assertion Method und URL Navigation Method deniert. Abb : Systemtest-Fassadenmodell Mit Hilfe dieser Fassadenmethoden wurde manuell ein Testfall im Test-Modell implementiert. Dieser ist in Abbildung 13.3 zu sehen. Der für diesen Testfall generierte Quelltext sowie das zugehörige Systemtest-Fassadeninterface sind im Anhang unter A.7 und A.8 abgebildet. Abb : Systemtest-Testmodell 126

139 Da der Versuch, die Systemtest-Fassade im Test-Modell zur Testfallbeschreibung zu verwenden, erfolgreich verlaufen war, wurde anschlieÿend auch die Generierung von Testfällen aus dem Test-Generatormodell evaluiert. Dazu wurden im Systemtest-Fassadenmodell weitere Create- und Delete-Methoden deniert. Mit diesen konnten anschlieÿend im Test-Generatormodell Duplication-Testmuster für Create-Methoden konguriert werden. Abbildung 13.4 zeigt einen Ausschnitt des Test-Generatormodells. Dort ist eine Testkonguration für die Entität Post abgebildet. Im unteren Teil der Abbildung sind die für die Testgenerierung benötigten Methodenabhängigkeiten zu sehen. Abb : Systemtest-Test-Generatormodell Anhand des Test-Generatormodells konnten erfolgreich Tests unter Benutzung der Systemtest-Fassade generiert werden. Dabei wurden 1167 LOC erzeugt. Es konnte gezeigt werden, dass mit dem Gargoyle-Test-Generator auch Tests für Fassaden generiert werden können, die andere Anwendungsarten bzw. Anwendungskomponenten abstrahieren Benutzerfreundlichkeit Die Evaluierung anhand der vorgestellten Anwendungsbeispiele hat gezeigt, dass die Generierung von Tests für Gargoyle-Anwendungen schnell und automatisiert durchgeführt werden kann. Nach einmaliger Einrichtung der MWE-Workows kann die Testgenerierung in wenigen Minuten durchgeführt werden. Dabei werden, auch bei kleinen Anwendungen mit nur wenigen Entitäten im zugrundeliegenden Domänenmodell, mehrere tausend Zeilen Quellcode generiert. Dies bedeutet eine hohe Zeitersparnis gegenüber der manuellen Implementierung von Tests. Die manuelle Spezikation von Tests oder die manuelle Anbindung von Fassaden an das Test-Generatormodell ist sehr aufwändig. Hier fehlt es an entsprechender Werkzeugunterstützung, um die Abhängigkeiten zwischen Methoden und Parametern besser verwalten zu können. 127

Ein Ansatz zum modellgetriebenen Integrationstest von EJB-basierten Informationssystemen

Ein Ansatz zum modellgetriebenen Integrationstest von EJB-basierten Informationssystemen 1 / 30 Ein Ansatz zum modellgetriebenen Integrationstest von EJB-basierten Informationssystemen Zwischenvortrag zur Diplomarbeit Steffen Conrad (235183) Research Group Software Construction RWTH Aachen

Mehr

Vortrag von: Ilias Agorakis & Robert Roginer

Vortrag von: Ilias Agorakis & Robert Roginer MDA Model Driven Architecture Vortrag von: Ilias Agorakis & Robert Roginer Anwendungen der SWT - WS 08/09 Inhalt Was ist MDA? Object Management Group (OMG) Ziele Konzepte der MDA Werkzeuge Vor- und Nachteile

Mehr

Model Driven Architecture

Model Driven Architecture Model Driven Architecture Wilhelm Stephan Universität Hamburg Fakultät für Mathematik, Informatik und Naturwissenschaften Seminar Softwareentwicklung in der Wissenschaft Betreuer: Julian Kunkel SommerSemester

Mehr

Diplomarbeit. Konzeption und Implementierung einer automatisierten Testumgebung. Thomas Wehrspann. 10. Dezember 2008

Diplomarbeit. Konzeption und Implementierung einer automatisierten Testumgebung. Thomas Wehrspann. 10. Dezember 2008 Konzeption und Implementierung einer automatisierten Testumgebung, 10. Dezember 2008 1 Gliederung Einleitung Softwaretests Beispiel Konzeption Zusammenfassung 2 Einleitung Komplexität von Softwaresystemen

Mehr

Agile Vorgehensmodelle in der Softwareentwicklung: Scrum

Agile Vorgehensmodelle in der Softwareentwicklung: Scrum C A R L V O N O S S I E T Z K Y Agile Vorgehensmodelle in der Softwareentwicklung: Scrum Johannes Diemke Vortrag im Rahmen der Projektgruppe Oldenburger Robot Soccer Team im Wintersemester 2009/2010 Was

Mehr

Was ist EMF? Wie wird EMF eingesetzt? Was ist ecore? Das Generatormodell Fazit

Was ist EMF? Wie wird EMF eingesetzt? Was ist ecore? Das Generatormodell Fazit Was ist EMF? Wie wird EMF eingesetzt? Was ist ecore? Das Generatormodell Fazit EMF ist ein eigenständiges Eclipse-Projekt (Eclipse Modeling Framework Project) EMF ist ein Modellierungsframework und Tool

Mehr

Copyright 2014 Delta Software Technology GmbH. All Rights reserved.

Copyright 2014 Delta Software Technology GmbH. All Rights reserved. Karlsruhe, 21. Mai 2014 Softwareentwicklung - Modellgetrieben und trotzdem agil Daniela Schilling Delta Software Technology GmbH The Perfect Way to Better Software Modellgetriebene Entwicklung Garant für

Mehr

Model Driven Architecture (MDA)

Model Driven Architecture (MDA) Model Driven Architecture (MDA) Vortrag im Fach Software Engineering II BA Mannheim / Fachrichtung Angewandte Informatik Torsten Hopp Gliederung Einleitung Motivation Grundzüge der MDA Ziele & Potenziale

Mehr

INNOVATOR im Entwicklungsprozess

INNOVATOR im Entwicklungsprozess Erfahrungsbericht INNOVATOR im Entwicklungsprozess Basis für Host- und Java-Anwendungen Dr. Carl-Werner Oehlrich, Principal Consultant MID GmbH Das Modellierungswerkzeug INNOVATOR Geschäftsprozess-Modellierung

Mehr

Daniel Warneke warneke@upb.de 08.05.2006. Ein Vortrag im Rahmen des Proseminars Software Pioneers

Daniel Warneke warneke@upb.de 08.05.2006. Ein Vortrag im Rahmen des Proseminars Software Pioneers Design Patterns Daniel Warneke warneke@upb.de 08.05.2006 Ein Vortrag im Rahmen des Proseminars Software Pioneers Design Patterns 1/23 Übersicht Einleitung / Motivation Design Patterns Beispiele Rolle des

Mehr

Modellbasierte Softwareentwicklung

Modellbasierte Softwareentwicklung CD OCL OD Statechart SD Modellbasierte Softwareentwicklung 7. Evolutionäre Methodik 7.1. Vorgehensmodell Vorlesungsnavigator: Prof. Dr. Bernhard Rumpe Sprache Codegen. http://www.se-rwth.de/ Testen Evolution

Mehr

Fassade. Objektbasiertes Strukturmuster. C. Restorff & M. Rohlfing

Fassade. Objektbasiertes Strukturmuster. C. Restorff & M. Rohlfing Fassade Objektbasiertes Strukturmuster C. Restorff & M. Rohlfing Übersicht Motivation Anwendbarkeit Struktur Teilnehmer Interaktion Konsequenz Implementierung Beispiel Bekannte Verwendung Verwandte Muster

Mehr

SDD System Design Document

SDD System Design Document SDD Software Konstruktion WS01/02 Gruppe 4 1. Einleitung Das vorliegende Dokument richtet sich vor allem an die Entwickler, aber auch an den Kunden, der das enstehende System verwenden wird. Es soll einen

Mehr

Handbuch ECDL 2003 Basic Modul 5: Datenbank Grundlagen von relationalen Datenbanken

Handbuch ECDL 2003 Basic Modul 5: Datenbank Grundlagen von relationalen Datenbanken Handbuch ECDL 2003 Basic Modul 5: Datenbank Grundlagen von relationalen Datenbanken Dateiname: ecdl5_01_00_documentation_standard.doc Speicherdatum: 14.02.2005 ECDL 2003 Basic Modul 5 Datenbank - Grundlagen

Mehr

Model Driven Architecture Praxisbeispiel

Model Driven Architecture Praxisbeispiel 1 EJOSA OpenUSS CampusSource Model Driven Architecture Praxisbeispiel 2 Situation von CampusSource-Plattformen Ähnliche Funktionen (Verwaltung von Studenten und Dozenten, Diskussionsforen,...), jedoch

Mehr

Model Driven Development im Überblick

Model Driven Development im Überblick Model Driven Development im Überblick Arif Chughtai Diplom-Informatiker (FH) www.digicomp-academy, Seite 1 September 05 Inhalt Motivation Überblick MDA Kleines Beispiel Werkzeuge www.digicomp-academy,

Mehr

SEA. Modellgetriebene Softwareentwicklung in der BA

SEA. Modellgetriebene Softwareentwicklung in der BA SEA Modellgetriebene Softwareentwicklung in der BA MDA bei der BA Ziele/Vorteile: für die Fachabteilung für die Systementwicklung für den Betrieb Wie wird MDA in der BA umgesetzt? Seite 2 MDA bei der BA

Mehr

Die Softwareentwicklungsphasen!

Die Softwareentwicklungsphasen! Softwareentwicklung Die Softwareentwicklungsphasen! Die Bezeichnungen der Phasen sind keine speziellen Begriffe der Informatik, sondern den allgemeinen Prinzipien zur Produktion integrierter Systeme entliehen.

Mehr

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren Lineargleichungssysteme: Additions-/ Subtraktionsverfahren W. Kippels 22. Februar 2014 Inhaltsverzeichnis 1 Einleitung 2 2 Lineargleichungssysteme zweiten Grades 2 3 Lineargleichungssysteme höheren als

Mehr

Softwareentwicklungspraktikum Sommersemester 2007. Feinentwurf

Softwareentwicklungspraktikum Sommersemester 2007. Feinentwurf Softwareentwicklungspraktikum Sommersemester 2007 Feinentwurf Auftraggeber Technische Universität Braunschweig

Mehr

Übungen zur Softwaretechnik

Übungen zur Softwaretechnik Technische Universität München Fakultät für Informatik Lehrstuhl IV: Software & Systems Engineering Markus Pister, Dr. Bernhard Rumpe WS 2002/2003 Lösungsblatt 9 17. Dezember 2002 www4.in.tum.de/~rumpe/se

Mehr

ActiveCharts. Verknüpfung von Modellen und Code bei der modellgetriebenen Softwareentwicklung mit UML 2.0

ActiveCharts. Verknüpfung von Modellen und Code bei der modellgetriebenen Softwareentwicklung mit UML 2.0 Jens Kohlmeyer 05. März 2007 Institut für Programmiermethodik und Compilerbau ActiveCharts Verknüpfung von Modellen und Code bei der modellgetriebenen Softwareentwicklung mit UML 2.0 Seite 2 Übersicht

Mehr

Comparing Software Factories and Software Product Lines

Comparing Software Factories and Software Product Lines Comparing Software Factories and Software Product Lines Martin Kleine kleine.martin@gmx.de Betreuer: Andreas Wuebbeke Agenda Motivation Zentrale Konzepte Software Produktlinien Software Factories Vergleich

Mehr

Testplan. Hochschule Luzern Technik & Architektur. Software Komponenten FS13. Gruppe 03 Horw, 16.04.2013

Testplan. Hochschule Luzern Technik & Architektur. Software Komponenten FS13. Gruppe 03 Horw, 16.04.2013 Software Komponenten FS13 Gruppe 03 Horw, 16.04.2013 Bontekoe Christian Estermann Michael Moor Simon Rohrer Felix Autoren Bontekoe Christian Studiengang Informatiker (Berufsbegleitend) Estermann Michael

Mehr

Prozessbewertung und -verbesserung nach ITIL im Kontext des betrieblichen Informationsmanagements. von Stephanie Wilke am 14.08.08

Prozessbewertung und -verbesserung nach ITIL im Kontext des betrieblichen Informationsmanagements. von Stephanie Wilke am 14.08.08 Prozessbewertung und -verbesserung nach ITIL im Kontext des betrieblichen Informationsmanagements von Stephanie Wilke am 14.08.08 Überblick Einleitung Was ist ITIL? Gegenüberstellung der Prozesse Neuer

Mehr

Java Enterprise Architekturen Willkommen in der Realität

Java Enterprise Architekturen Willkommen in der Realität Java Enterprise Architekturen Willkommen in der Realität Ralf Degner (Ralf.Degner@tk-online.de), Dr. Frank Griffel (Dr.Frank.Griffel@tk-online.de) Techniker Krankenkasse Häufig werden Mehrschichtarchitekturen

Mehr

Softwareentwicklungspraktikum Sommersemester 2007. Grobentwurf

Softwareentwicklungspraktikum Sommersemester 2007. Grobentwurf Softwareentwicklungspraktikum Sommersemester 2007 Grobentwurf Auftraggeber Technische Universität Braunschweig

Mehr

Softwaretechnik. Fomuso Ekellem WS 2011/12

Softwaretechnik. Fomuso Ekellem WS 2011/12 WS 2011/12 Inhalt Projektvorstellung Übung 1 Wiederholung zusammengefasst Planungsphase Lernziele Ziele und Inhalt der Planungsphase Anlass und Aufgabestellung(Was ist dabei erförderlich) Requirement Engineering

Mehr

StuPro-Seminar Dokumentation in der Software-Wartung. StuPro-Seminar Probleme und Schwierigkeiten in der Software-Wartung.

StuPro-Seminar Dokumentation in der Software-Wartung. StuPro-Seminar Probleme und Schwierigkeiten in der Software-Wartung. StuPro-Seminar Dokumentation in der Software-Wartung StuPro-Seminar Probleme und Schwierigkeiten in der Software-Wartung Folie 1/xx Software-Wartung: theoretisch Ausgangslage eigentlich simpel: fertige

Mehr

Design Pattern - Strukturmuster. CAS SWE - OOAD Marco Hunziker Klaus Imfeld Frédéric Bächler Marcel Lüthi

Design Pattern - Strukturmuster. CAS SWE - OOAD Marco Hunziker Klaus Imfeld Frédéric Bächler Marcel Lüthi Design Pattern - Strukturmuster CAS SWE - OOAD Marco Hunziker Klaus Imfeld Frédéric Bächler Marcel Lüthi Agenda Einleitung Strukturmuster Fassade Model View Controller Vergleich 2 Einleitung Strukturmuster

Mehr

Objektorientierter Software-Entwurf Grundlagen 1 1. Analyse Design Implementierung. Frühe Phasen durch Informationssystemanalyse abgedeckt

Objektorientierter Software-Entwurf Grundlagen 1 1. Analyse Design Implementierung. Frühe Phasen durch Informationssystemanalyse abgedeckt Objektorientierter Software-Entwurf Grundlagen 1 1 Einordnung der Veranstaltung Analyse Design Implementierung Slide 1 Informationssystemanalyse Objektorientierter Software-Entwurf Frühe Phasen durch Informationssystemanalyse

Mehr

Praktikum Grundlagen der Programmierung. Diverse Grundlagen. Dr. Karsten Tolle

Praktikum Grundlagen der Programmierung. Diverse Grundlagen. Dr. Karsten Tolle Diverse Grundlagen Dr. Karsten Tolle Vorgehensmodelle im Software Engineering Wasserfallmodell Rapid Prototyping Spiralmodell V-Modell Rational Unified Process extrem Programming Test Driven Development

Mehr

Softwarequalität: Zusammenfassung und Ausblick. 17. Juli 2013

Softwarequalität: Zusammenfassung und Ausblick. 17. Juli 2013 Softwarequalität: Zusammenfassung und Ausblick 17. Juli 2013 Überblick Rückblick: Qualitätskriterien Qualitätsmanagement Qualitätssicherungsmaßnahmen Thesen zur Softwarequalität Ausblick: Lehrveranstaltungen

Mehr

Naked-FHIR. Code-Generierung auf Basis von HL7 FHIR Andreas Schuler, MSc. Textmasterformate durch Klicken bearbeiten

Naked-FHIR. Code-Generierung auf Basis von HL7 FHIR Andreas Schuler, MSc. Textmasterformate durch Klicken bearbeiten Naked-FHIR Code-Generierung auf Basis von HL7 FHIR Andreas Schuler, MSc. HL7 Jahrestagung 2015 18. März 2015 Einführung HL7 FHIR stellt eine Reihe an Basis-Ressourcen zur Verfügung Über Zweite Conformance

Mehr

Fachbericht zum Thema: Anforderungen an ein Datenbanksystem

Fachbericht zum Thema: Anforderungen an ein Datenbanksystem Fachbericht zum Thema: Anforderungen an ein Datenbanksystem von André Franken 1 Inhaltsverzeichnis 1 Inhaltsverzeichnis 1 2 Einführung 2 2.1 Gründe für den Einsatz von DB-Systemen 2 2.2 Definition: Datenbank

Mehr

Dr. Hanno Schauer Mons-Tabor-Gymnasium Montabaur. UML-Klassendiagramme als Werkzeug im Unterricht

Dr. Hanno Schauer Mons-Tabor-Gymnasium Montabaur. UML-Klassendiagramme als Werkzeug im Unterricht Dr. Hanno Schauer Mons-Tabor-Gymnasium Montabaur UML-Klassendiagramme als Werkzeug im Unterricht Blitzlicht? In welcher Programmiersprache(n) unterrichten Sie?? In welchem Umfang unterrichten Sie Objektorientierung??

Mehr

Einführung in modellgetriebene Softwareentwicklung. 24. Oktober 2012

Einführung in modellgetriebene Softwareentwicklung. 24. Oktober 2012 Einführung in modellgetriebene Softwareentwicklung 24. Oktober 2012 Überblick Was sind die Grundprinzipien der modellgetriebenen Softwareentwicklung? Entwicklung einer MDD-Infrastruktur Modellgetriebene

Mehr

Komponententest. Testen von Software Systemen. Übung 02 SS 2009 Version: 1.0 09.06.2009

Komponententest. Testen von Software Systemen. Übung 02 SS 2009 Version: 1.0 09.06.2009 Testen von Software Systemen Übung 02 SS 2009 Version: 1.0 09.06.2009 Komponententest Kunde: Dr. Reinhold Plösch Dr. Johannes Sametinger Kundenreferenz: 259.019 Team 19 Mitarbeiter: Christian Märzinger

Mehr

Model Driven Architecture

Model Driven Architecture { AKTUELLES SCHLAGWORT* / MODEL DRIVEN ARCHITECTURE Model Driven Architecture Martin Kempa Zoltán Ádám Mann Bei der Model Driven Architecture (MDA) bilden Modelle die zentralen Elemente des Softwareentwicklungsprozesses.

Mehr

Das System sollte den Benutzer immer auf dem Laufenden halten, indem es angemessenes Feedback in einer angemessenen Zeit liefert.

Das System sollte den Benutzer immer auf dem Laufenden halten, indem es angemessenes Feedback in einer angemessenen Zeit liefert. Usability Heuristiken Karima Tefifha Proseminar: "Software Engineering Kernkonzepte: Usability" 28.06.2012 Prof. Dr. Kurt Schneider Leibniz Universität Hannover Die ProSeminar-Ausarbeitung beschäftigt

Mehr

Softwaretests in Visual Studio 2010 Ultimate Vergleich mit Java-Testwerkzeugen. Alexander Schunk Marcel Teuber Henry Trobisch

Softwaretests in Visual Studio 2010 Ultimate Vergleich mit Java-Testwerkzeugen. Alexander Schunk Marcel Teuber Henry Trobisch Softwaretests in Visual Studio 2010 Ultimate Vergleich mit Java-Testwerkzeugen Alexander Schunk Henry Trobisch Inhalt 1. Vergleich der Unit-Tests... 2 2. Vergleich der Codeabdeckungs-Tests... 2 3. Vergleich

Mehr

C++11 C++14 Kapitel Doppelseite Übungen Musterlösungen Anhang

C++11 C++14 Kapitel Doppelseite Übungen Musterlösungen Anhang Einleitung Dieses Buch wendet sich an jeden Leser, der die Programmiersprache C++ neu lernen oder vertiefen möchte, egal ob Anfänger oder fortgeschrittener C++-Programmierer. C++ ist eine weitgehend plattformunabhängige

Mehr

Übung 6: Feinentwurf. Prof. Dr. Dr. h.c. Manfred Broy Dr. Herbert Ehler, Martin Feilkas 6. Juli 2006 Bernd Spanfelner, Sebastian Winter

Übung 6: Feinentwurf. Prof. Dr. Dr. h.c. Manfred Broy Dr. Herbert Ehler, Martin Feilkas 6. Juli 2006 Bernd Spanfelner, Sebastian Winter Prof. Dr. Dr. h.c. Manfred Broy Sommersemester Dr. Herbert Ehler, Martin Feilkas 6. Juli 2006 Bernd Spanfelner, Sebastian Winter Einführung in die Softwaretechnik Übung 6: Feinentwurf Aufgabe 17: Entwurfsmuster

Mehr

Data Lineage goes Traceability - oder was Requirements Engineering von Business Intelligence lernen kann

Data Lineage goes Traceability - oder was Requirements Engineering von Business Intelligence lernen kann Data Lineage goes Traceability - oder was Requirements Engineering von Business Intelligence lernen kann Andreas Ditze MID GmbH Kressengartenstraße 10 90402 Nürnberg a.ditze@mid.de Abstract: Data Lineage

Mehr

Einführung in Generatives Programmieren. Bastian Molkenthin

Einführung in Generatives Programmieren. Bastian Molkenthin Einführung in Generatives Programmieren Bastian Molkenthin Motivation Industrielle Entwicklung *!!*,(% % - #$% #!" + '( & )!* Softwareentwicklung Rückblick auf Objektorientierung Objektorientierte Softwareentwicklung

Mehr

Integration mit. Wie AristaFlow Sie in Ihrem Unternehmen unterstützen kann, zeigen wir Ihnen am nachfolgenden Beispiel einer Support-Anfrage.

Integration mit. Wie AristaFlow Sie in Ihrem Unternehmen unterstützen kann, zeigen wir Ihnen am nachfolgenden Beispiel einer Support-Anfrage. Integration mit Die Integration der AristaFlow Business Process Management Suite (BPM) mit dem Enterprise Information Management System FILERO (EIMS) bildet die optimale Basis für flexible Optimierung

Mehr

Kapitel 2: Der Software-Entwicklungsprozess

Kapitel 2: Der Software-Entwicklungsprozess Wie konstruiert man Software? Kapitel 2: Der Software-Entwicklungsprozess SoPra 2008 Kap. 2: Der Software-Entwicklungsprozess (1/10) Der Software-Entwicklungs-Prozess Historisches 1960JJ adhoc Techniken

Mehr

Online Banking System

Online Banking System Online Banking System Pflichtenheft im Rahmen des WI-Praktikum bei Thomas M. Lange Fachhochschule Giessen-Friedberg Fachbereich MNI Studiengang Informatik Erstellt von: Eugen Riske Yueksel Korkmaz Alper

Mehr

Modellgetriebene Entwicklungsprozesse in der Praxis - eine Bestandsaufnahme. Tillmann Schall, anaptecs GmbH

Modellgetriebene Entwicklungsprozesse in der Praxis - eine Bestandsaufnahme. Tillmann Schall, anaptecs GmbH Modellgetriebene Entwicklungsprozesse in der Praxis - eine Bestandsaufnahme Tillmann Schall, anaptecs GmbH : Agenda Grundlagen modellgetriebener Entwicklungsprozesse Schritte zur Einführung Erfahrungen

Mehr

Neue Funktionen in Innovator 11 R5

Neue Funktionen in Innovator 11 R5 Neue Funktionen in Innovator 11 R5 Innovator for Enterprise Architects, Java Harvester und Prüfassistent 12.11.2013 Agenda 1 2 3 Einführung Was ist neu in Innovator 11 R5? Szenario Enterprise Architektur

Mehr

extreme Programming (XP) Hermann Götz Sergij Paholchak Agenda Was ist XP? Grundprinzipien Der Entwicklungsprozess Die Projektplanung Praktiken Vorteile und Nachteile Wann macht XP Sinn für ein Projekt?

Mehr

Klausur WS 2006/07 Programmiersprache Java Objektorientierte Programmierung II 15. März 2007

Klausur WS 2006/07 Programmiersprache Java Objektorientierte Programmierung II 15. März 2007 Fachhochschule Bonn-Rhein-Sieg University of Applied Sciences Fachbereich Informatik Prof. Dr. Peter Becker Klausur WS 2006/07 Programmiersprache Java Objektorientierte Programmierung II 15. März 2007

Mehr

Ist Excel das richtige Tool für FMEA? Steve Murphy, Marc Schaeffers

Ist Excel das richtige Tool für FMEA? Steve Murphy, Marc Schaeffers Ist Excel das richtige Tool für FMEA? Steve Murphy, Marc Schaeffers Ist Excel das richtige Tool für FMEA? Einleitung Wenn in einem Unternehmen FMEA eingeführt wird, fangen die meisten sofort damit an,

Mehr

Softwareentwicklungsprozess im Praktikum. 23. April 2015

Softwareentwicklungsprozess im Praktikum. 23. April 2015 Softwareentwicklungsprozess im Praktikum 23. April 2015 Agile Softwareentwicklung Eine agile Methodik stellt die beteiligten Menschen in den Mittelpunkt und versucht die Kommunikation und Zusammenarbeit

Mehr

Klausur zu den Teilgebieten Software-Management und Software-Qualitätsmanagement

Klausur zu den Teilgebieten Software-Management und Software-Qualitätsmanagement Klausur zu den Teilgebieten Software-Management und Software-Qualitätsmanagement Prof. K.-P. Fähnrich, Prof. H.-G. Gräbe, T. Riechert Institut für Informatik Sommersemester 2012 Allgemeine Bemerkungen

Mehr

Übungsklausur vom 7. Dez. 2007

Übungsklausur vom 7. Dez. 2007 Übungsklausur vom 7. Dez. 2007 Ein Lösungsmuster Teilbereiche der Softwaretechnik Software Anforderungen Software Entwurf Software Konstruktion Software Test Software Wartung Software Konfigurationsmanagement

Mehr

Web Services stellen eine Integrationsarchitektur dar, die die Kommunikation zwischen verschiedenen Anwendungen

Web Services stellen eine Integrationsarchitektur dar, die die Kommunikation zwischen verschiedenen Anwendungen 9 3 Web Services 3.1 Überblick Web Services stellen eine Integrationsarchitektur dar, die die Kommunikation zwischen verschiedenen Anwendungen mit Hilfe von XML über das Internet ermöglicht (siehe Abb.

Mehr

IT-Governance und Social, Mobile und Cloud Computing: Ein Management Framework... Bachelorarbeit

IT-Governance und Social, Mobile und Cloud Computing: Ein Management Framework... Bachelorarbeit IT-Governance und Social, Mobile und Cloud Computing: Ein Management Framework... Bachelorarbeit zur Erlangung des akademischen Grades Bachelor of Science (B.Sc.) im Studiengang Wirtschaftswissenschaft

Mehr

Generatives Programmieren

Generatives Programmieren Generatives Programmieren Seminar Produktlinien WS03/04 Tammo van Lessen 08.01.2004 Outline Einleitung Generatoren Generatives Programmieren Fazit Einleitung Industrielle Entwicklung 1826 Austauschbare

Mehr

Software Systems Engineering

Software Systems Engineering Software : SoSe 08 Prof. Dr. Klaus Schmid Software Produktlinien Ein neues Programm soll erstellt werden. Das habe ich doch schon mal programmiert, oder? Alter Code passt aber nicht ganz! Wird passend

Mehr

Generative Prozessmodelle Patrick Otto MDD Konferenz 22.03.2009

Generative Prozessmodelle Patrick Otto MDD Konferenz 22.03.2009 Generative Prozessmodelle Patrick Otto MDD Konferenz 22.03.2009 Gliederung 1. Generative Programmierung 2. Möglichkeiten und Einsatzgebiet 3. Prozess / Tools 4. Zusammenfassung 19.03.2009 GENERATIVE PROGRAMMIERUNG

Mehr

Research Note zum Thema: Laufzeit von Support-Leistungen für Server OS

Research Note zum Thema: Laufzeit von Support-Leistungen für Server OS Research Note zum Thema: Laufzeit von Support-Leistungen für Axel Oppermann Advisor phone: +49 561 506975-24 mobile: +49 151 223 223 00 axel.oppermann@experton-group.com November 2009 Inhalt 1 EINFÜHRUNG

Mehr

Software Engineering. Sommersemester 2012, Dr. Andreas Metzger

Software Engineering. Sommersemester 2012, Dr. Andreas Metzger Software Engineering (Übungsblatt 2) Sommersemester 2012, Dr. Andreas Metzger Übungsblatt-Themen: Prinzip, Technik, Methode und Werkzeug; Arten von Wartung; Modularität (Kohäsion/ Kopplung); Inkrementelle

Mehr

Informationssystemanalyse Problemstellung 2 1. Trotz aller Methoden, Techniken usw. zeigen Untersuchungen sehr negative Ergebnisse:

Informationssystemanalyse Problemstellung 2 1. Trotz aller Methoden, Techniken usw. zeigen Untersuchungen sehr negative Ergebnisse: Informationssystemanalyse Problemstellung 2 1 Problemstellung Trotz aller Methoden, Techniken usw. zeigen Untersuchungen sehr negative Ergebnisse: große Software-Systeme werden im Schnitt ein Jahr zu spät

Mehr

Softwaretechnik (Allgemeine Informatik) Überblick

Softwaretechnik (Allgemeine Informatik) Überblick Softwaretechnik (Allgemeine Informatik) Überblick 1 Einführung und Überblick 2 Abstraktion 3 Objektorientiertes Vorgehensmodell 4 Methoden der Anforderungs- und Problembereichsanalyse 5 UML-Diagramme 6

Mehr

Use Cases. Use Cases

Use Cases. Use Cases Use Cases Eigenschaften: Ein Use Case beschreibt einen Teil des Verhaltens eines Systems aus externer Sicht (Formuliert in der der Fachsprache der Anwendung) Dies geschieht, indem ein Systemdialog beschrieben

Mehr

1 Informationelle Systeme begriffliche Abgrenzung

1 Informationelle Systeme begriffliche Abgrenzung 1 Informationelle Systeme begriffliche Abgrenzung Im Titel dieses Buches wurde das Wort Softwaresystem an den Anfang gestellt. Dies ist kein Zufall, denn es soll einen Hinweis darauf geben, dass dieser

Mehr

Speicher in der Cloud

Speicher in der Cloud Speicher in der Cloud Kostenbremse, Sicherheitsrisiko oder Basis für die unternehmensweite Kollaboration? von Cornelius Höchel-Winter 2013 ComConsult Research GmbH, Aachen 3 SYNCHRONISATION TEUFELSZEUG

Mehr

Datenübernahme easyjob 3.0 zu easyjob 4.0

Datenübernahme easyjob 3.0 zu easyjob 4.0 Datenübernahme easyjob 3.0 zu easyjob 4.0 Einführung...3 Systemanforderung easyjob 4.0...3 Vorgehensweise zur Umstellung zu easyjob 4.0...4 Installation easyjob 4.0 auf dem Server und Arbeitsstationen...4

Mehr

EoL-Testautomation 2.0. Technische Beschreibung. DI Hans-Peter Haberlandner. Blumatix GmbH

EoL-Testautomation 2.0. Technische Beschreibung. DI Hans-Peter Haberlandner. Blumatix GmbH EoL-Testautomation 2.0 Technische Beschreibung DI Hans-Peter Haberlandner Blumatix GmbH EoL-Testautomation 2.0 Technische Beschreibung Die Herausforderung Die Software spielt im Bereich der Testautomation

Mehr

Robot Karol für Delphi

Robot Karol für Delphi Robot Karol für Delphi Reinhard Nitzsche, OSZ Handel I Version 0.1 vom 24. Januar 2003 Zusammenfassung Nach der Einführung in die (variablenfreie) Programmierung mit Robot Karol von Freiberger und Krško

Mehr

Typisierung des Replikationsplan Wirries, Denis Datenbankspezialist

Typisierung des Replikationsplan Wirries, Denis Datenbankspezialist Typisierung des Replikationsplan Wirries, Denis Datenbankspezialist Feintypisierung - Überblick Ergebnisse Ergebnisse aus aus anderen anderen Arbeitsergebnissen Arbeitsergebnissen Replikationsplan Replikationsplan

Mehr

Content Management System mit INTREXX 2002.

Content Management System mit INTREXX 2002. Content Management System mit INTREXX 2002. Welche Vorteile hat ein CM-System mit INTREXX? Sie haben bereits INTREXX im Einsatz? Dann liegt es auf der Hand, dass Sie ein CM-System zur Pflege Ihrer Webseite,

Mehr

Das Pflichtenheft. Dipl.- Ing. Dipl.-Informatiker Dieter Klapproth Ains A-Systemhaus GmbH Berlin

Das Pflichtenheft. Dipl.- Ing. Dipl.-Informatiker Dieter Klapproth Ains A-Systemhaus GmbH Berlin Fragestellungen: Warum reicht das Lastenheft nicht aus? Was kann ich mit dem Lastenheft machen? Was unterscheidet das Pflichtenheft vom Lastenheft? Was gehört zum Auftragsumfang einer Individualsoftware?

Mehr

Kompetenz. rund um. Ihren. Entwicklungsprozess. Über uns. Technische Software. Modellbasierter Test. Prüfplätze. Automatisierung.

Kompetenz. rund um. Ihren. Entwicklungsprozess. Über uns. Technische Software. Modellbasierter Test. Prüfplätze. Automatisierung. Kompetenz rund um Ihren Entwicklungsprozess Modellieren für den Test - Segen oder Fluch? Firmenpräsentation auf der embeddedworld 2010 Dipl. Ing. (Univ) Gerhard Baier Bereichsleiter Marketing und Vertrieb

Mehr

Objektorientierte Programmierung für Anfänger am Beispiel PHP

Objektorientierte Programmierung für Anfänger am Beispiel PHP Objektorientierte Programmierung für Anfänger am Beispiel PHP Johannes Mittendorfer http://jmittendorfer.hostingsociety.com 19. August 2012 Abstract Dieses Dokument soll die Vorteile der objektorientierten

Mehr

Klassenentwurf. Wie schreiben wir Klassen, die leicht zu verstehen, wartbar und wiederverwendbar sind? Objektorientierte Programmierung mit Java

Klassenentwurf. Wie schreiben wir Klassen, die leicht zu verstehen, wartbar und wiederverwendbar sind? Objektorientierte Programmierung mit Java Objektorientierte Programmierung mit Java Eine praxisnahe Einführung mit BlueJ Klassenentwurf Wie schreiben wir Klassen, die leicht zu verstehen, wartbar und wiederverwendbar sind? 1.0 Zentrale Konzepte

Mehr

Java Entwicklung für Embedded Devices Best & Worst Practices!

Java Entwicklung für Embedded Devices Best & Worst Practices! Java Entwicklung für Embedded Devices! George Mesesan Microdoc GmbH Natürlich können wir dieses neue log4j Bundle auch auf dem Device verwenden. Ist doch alles Java. Java Micro Edition (ME) Java Standard

Mehr

Erweiterung eines SMIL Players für die Darstellung von Transparenzen und SVG Inhalten

Erweiterung eines SMIL Players für die Darstellung von Transparenzen und SVG Inhalten Bachlor-Abschlussarbeit Erweiterung eines SMIL Players für die Darstellung von Transparenzen und SVG Inhalten im Studiengang Informatik der Fakultät IV - Wirtschaft und Informatik Sommersemester 2009 Burim

Mehr

MO 27. Aug. 2007, 17:00 UHR JAVA FRAMEWORKS TIPPS VON PROFI-GÄRTNERN GEGEN WILDWUCHS

MO 27. Aug. 2007, 17:00 UHR JAVA FRAMEWORKS TIPPS VON PROFI-GÄRTNERN GEGEN WILDWUCHS 072 MO 27. Aug. 2007, 17:00 UHR JAVA FRAMEWORKS TIPPS VON PROFI-GÄRTNERN GEGEN WILDWUCHS Die Flut von Open Source Frameworks ist vergleichbar mit dem Markt von kommerziellen Produkten Es gibt eine Vielzahl

Mehr

Einführung in Eclipse und Java

Einführung in Eclipse und Java Universität Bayreuth Lehrstuhl für Angewandte Informatik IV Datenbanken und Informationssysteme Prof. Dr.-Ing. Jablonski Einführung in Eclipse und Java Dipl.Inf. Manuel Götz Lehrstuhl für Angewandte Informatik

Mehr

1 Mathematische Grundlagen

1 Mathematische Grundlagen Mathematische Grundlagen - 1-1 Mathematische Grundlagen Der Begriff der Menge ist einer der grundlegenden Begriffe in der Mathematik. Mengen dienen dazu, Dinge oder Objekte zu einer Einheit zusammenzufassen.

Mehr

Albert HAYR Linux, IT and Open Source Expert and Solution Architect. Open Source professionell einsetzen

Albert HAYR Linux, IT and Open Source Expert and Solution Architect. Open Source professionell einsetzen Open Source professionell einsetzen 1 Mein Background Ich bin überzeugt von Open Source. Ich verwende fast nur Open Source privat und beruflich. Ich arbeite seit mehr als 10 Jahren mit Linux und Open Source.

Mehr

Proseminar: Website-Managment-System. NetObjects Fusion. von Christoph Feller

Proseminar: Website-Managment-System. NetObjects Fusion. von Christoph Feller Proseminar: Website-Managment-System NetObjects Fusion von Christoph Feller Netobjects Fusion - Übersicht Übersicht Einleitung Die Komponenten Übersicht über die Komponenten Beschreibung der einzelnen

Mehr

Diese Ansicht erhalten Sie nach der erfolgreichen Anmeldung bei Wordpress.

Diese Ansicht erhalten Sie nach der erfolgreichen Anmeldung bei Wordpress. Anmeldung http://www.ihredomain.de/wp-admin Dashboard Diese Ansicht erhalten Sie nach der erfolgreichen Anmeldung bei Wordpress. Das Dashboard gibt Ihnen eine kurze Übersicht, z.b. Anzahl der Beiträge,

Mehr

Autorisierung. Sicherheit und Zugriffskontrolle & Erstellen einer Berechtigungskomponente

Autorisierung. Sicherheit und Zugriffskontrolle & Erstellen einer Berechtigungskomponente Autorisierung Sicherheit und Zugriffskontrolle & Erstellen einer Berechtigungskomponente Dokumentation zum Referat von Matthias Warnicke und Joachim Schröder Modul: Komponenten basierte Softwareentwickelung

Mehr

Telling TestStories Modellbasiertes Akzeptanz Testen Serviceorientierter Systeme

Telling TestStories Modellbasiertes Akzeptanz Testen Serviceorientierter Systeme Telling TestStories Modellbasiertes Akzeptanz Testen Serviceorientierter Systeme Michael Felderer Workshop Requirements Engineering meets Testing Bad Honnef, 5. Juni 2008 1 Überblick Grundbegriffe Motivation

Mehr

ZENITY - Die Software für Ihre Unternehmens-Releaseplanung

ZENITY - Die Software für Ihre Unternehmens-Releaseplanung ZENITY - Die Software für Ihre Unternehmens-Releaseplanung RELEASEPLANUNG HEUTE Heutige Anwendungen in in Grossunternehmen sind sind keine keine alleinstehenden alleinstehenden Insel-Applikationen Insel-Applikationen

Mehr

Erfolg ist programmierbar.

Erfolg ist programmierbar. 4578954569774981234656895856512457895456977498 3465689585651245789545697749812346568958561245 9545697749812346568958565124578954569774981234 6895856512457895456977498123465689585612457895 6977498123465689585651245789545697749812346568

Mehr

Analyse zum Thema: Laufzeit von Support-Leistungen für ausgewählte Server OS

Analyse zum Thema: Laufzeit von Support-Leistungen für ausgewählte Server OS Analyse zum Thema: Laufzeit von Support-Leistungen für Axel Oppermann Advisor phone: +49 561 506975-24 mobile: +49 151 223 223 00 axel.oppermann@experton-group.com Januar 2010 Inhalt Summary und Key Findings

Mehr

Fachdidaktik der Informatik 18.12.08 Jörg Depner, Kathrin Gaißer

Fachdidaktik der Informatik 18.12.08 Jörg Depner, Kathrin Gaißer Fachdidaktik der Informatik 18.12.08 Jörg Depner, Kathrin Gaißer Klassendiagramme Ein Klassendiagramm dient in der objektorientierten Softwareentwicklung zur Darstellung von Klassen und den Beziehungen,

Mehr

16 Architekturentwurf Einführung und Überblick

16 Architekturentwurf Einführung und Überblick Teil III: Software-Architekturentwurf 16 Architekturentwurf Einführung und Überblick 16.1 Software entwerfen Warum? Beim Arbeiten im Kleinen nicht oder nur ansatzweise (Detailentwurf) Größere Software

Mehr

Modellgetriebene Service-Entwicklung

Modellgetriebene Service-Entwicklung Modellgetriebene Service-Entwicklung Service-orientierte Architekturen (SOA), Prof. Dr. M. Jäger Johannes Tietje 24. Juni 2010 1 / 13 Motivation konkrete Teile eines Dienstes Rahmenimplementierung der

Mehr

Informationssystemanalyse Grundlagen 1 1

Informationssystemanalyse Grundlagen 1 1 Informationssystemanalyse Grundlagen 1 1 Software-Projekte Klassischerweise wird Software-Entwicklung in Projektform abgewickelt. Projekte kommen dabei zwischen einem Anbieter und einem Kunden zustande,

Mehr

Suche schlecht beschriftete Bilder mit Eigenen Abfragen

Suche schlecht beschriftete Bilder mit Eigenen Abfragen Suche schlecht beschriftete Bilder mit Eigenen Abfragen Ist die Bilderdatenbank über einen längeren Zeitraum in Benutzung, so steigt die Wahrscheinlichkeit für schlecht beschriftete Bilder 1. Insbesondere

Mehr

Software-Qualität im Rahmen modellgetriebener Softwareentwicklung

Software-Qualität im Rahmen modellgetriebener Softwareentwicklung Software-Qualität im Rahmen modellgetriebener Softwareentwicklung OFFIS Technologiecluster Enterprise Application Integration niels.streekmann@offis.de 09.07.2008 Seite 1 / 13 Software-Qualität: Unterschiedliche

Mehr

Einleitung: Frontend Backend

Einleitung: Frontend Backend Die Internetseite des LSW Deutschland e.v. hat ein neues Gesicht bekommen. Ab dem 01.01.2012 ist sie in Form eines Content Management Systems (CMS) im Netz. Einleitung: Die Grundlage für die Neuprogrammierung

Mehr

EinfÅhrung in die objektorientiere Programmierung (OOP) unter Delphi 6.0. EDV Kurs 13/2

EinfÅhrung in die objektorientiere Programmierung (OOP) unter Delphi 6.0. EDV Kurs 13/2 EinfÅhrung in die objektorientiere Programmierung (OOP) unter Delphi 6.0 EDV Kurs 13/2 Inhaltsverzeichnis 1 Objekte... 1 2 Klassen... 3 2.1 Beziehungen zwischen Klassen... 4 2.1.1 Vererbung... 4 2.1.2

Mehr

Beispielhaft MDSD in der Praxis. Dr. Shota Okujava shota.okujava@isento.de www.isento.de

Beispielhaft MDSD in der Praxis. Dr. Shota Okujava shota.okujava@isento.de www.isento.de Beispielhaft MDSD in der Praxis Dr. Shota Okujava shota.okujava@isento.de www.isento.de Agenda Einführung Softwareentwicklungsprozess und MDSD Technologien und Werkzeuge Demo Entwicklung der Metamodelle

Mehr