Download - FernUniversit¤t in Hagen

91

Transcript of Download - FernUniversit¤t in Hagen

Fernuniversität in HagenFakultät für Mathematik und InformatikLehrgebiet ProgrammiersystemeProf. Dr. Friedrich Steimann

Abschlussarbeit im Studiengang

Master of Computer Science

Implementierung eines

Eclipse-Plugins

zum automatisierten Testen von

Refaktorisierungswerkzeugen

Osama El Hosami

Matrikelnummer: 7124724

18. August 2010

Betreuer:

Christian Kollee

Hiermit versichere ich, dass ich die vorliegende Arbeit selbstständig und nur mit denangegebenen Hilfsmitteln angefertigt habe. Wörtlich oder inhaltlich übernommene Lite-raturquellen wurden besonders gekennzeichnet.

Osama El HosamiMinden, August 2010

2

Inhaltsangabe

Durch Refaktorisierungen werden bedeutungserhaltende Änderungen an Programmendurchgeführt. Diese verfolgen das Ziel, dem schleichenden Prozess der Verschlechterungder Softwarequalität (�Softwarefäulnis�) entgegen zu wirken und sind damit bei der War-tung von Programmen, zumindest auf lange Sicht, unverzichtbar. [26] Heutige Entwick-lungsumgebungen, wie z.B. Eclipse, NetBeans oder Visual-Studio, bieten Werkzeugunter-stützung zur automatisierten Anwendung von Refaktorisierungen an. Viele der existieren-den Refaktorisierungswerkzeuge bleiben jedoch hinter den gestellten Erwartungen, so dassdiese nicht korrekt Arbeiten und Fehler einführen [25]. Die Fehler, die dabei durch Anwen-dung von Refaktorisierungswerkzeugen in ein Programm eingeführt werden, reichen vonÜbersetzungsfehlern bis hin zu Verhaltensänderungen, die bestenfalls im Zuge des Testensaufgedeckt werden oder gänzlich unentdeckt bleiben. Um jedoch die Qualität von Refak-torisierungswerkzeugen nachhaltig zu verbessern, bietet sich, wie für andere Programmeauch, das Testen an. Mit dem Refactoring Tool Tester aus dieser Arbeit steht eine Refer-enzimplementierung für das automatisierte Testen von Java-Refaktorisierungswerkzeugenin Eclipse zur Verfügung.

3

Inhaltsverzeichnis

Abbildungsverzeichnis 7

Tabellenverzeichnis 9

1 Einleitung 101.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101.2 Problemstellung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111.3 Aufbau der Arbeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2 Begri�sde�nitionen 15

3 Lösungsansatz 193.1 Vorgehensweise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193.2 Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.3 Ablauf von Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263.4 Steuerung und Überwachung von Aktoren . . . . . . . . . . . . . . . . . . 283.5 Testfälle für Refaktorisierungswerkzeuge . . . . . . . . . . . . . . . . . . . 293.6 Grundlagen und Hilfsmittel . . . . . . . . . . . . . . . . . . . . . . . . . . 31

4 Implementierung 404.1 Organisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

4.1.1 Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404.1.2 Abhängigkeiten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414.1.3 Pakete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

4.2 Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424.2.1 Struktur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424.2.2 Modell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454.2.3 Kon�guration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494.2.4 Erweiterung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

4.3 Benutzerinterface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

5 Diskussion 615.1 Interpretation und Bewertung . . . . . . . . . . . . . . . . . . . . . . . . . 615.2 Vergleich mit verwandten Arbeiten . . . . . . . . . . . . . . . . . . . . . . 63

6 Schlussbetrachtungen 656.1 Zusammenfassung und Fazit . . . . . . . . . . . . . . . . . . . . . . . . . . 65

4

Inhaltsverzeichnis

6.2 Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

Literaturverzeichnis 67

Literaturverzeichnis 67

A Paketstruktur 70

B Schnellstartanleitung 73B.1 Installation und Deinstallation . . . . . . . . . . . . . . . . . . . . . . . . . 73

B.1.1 Auslieferung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73B.1.2 Voraussetzungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73B.1.3 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74B.1.4 Deinstallation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

B.2 Erzeugen von Testprojekten . . . . . . . . . . . . . . . . . . . . . . . . . . 77B.3 Erzeugen von Kon�gurationen . . . . . . . . . . . . . . . . . . . . . . . . . 81

B.3.1 Bereitstellung von Probanden-Projekten . . . . . . . . . . . . . . . 81B.3.2 Launch-Kon�guration . . . . . . . . . . . . . . . . . . . . . . . . . 86

B.4 Debuggen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

C CD Inhaltsverzeichnis 91

5

Abkürzungsverzeichnis

API Application Programming InterfaceAWT Abstract Window ToolkitCOM Component Object ModelCORBA Common Object Request Broker ArchitectureCSV Comma-Separated ValuesCVS Concurrent Version SystemDbC Design by ContractDCOM Distributed Component Object ModelDSL Domain-speci�c languageGC Garbage CollectorHTML Hypertext Markup LanguageIDE integrierte EntwicklungsumgebungJDT Java Development ToolsJVM virtuelle Java-MaschineMVC Model-View-ControllerOSGi Open Services Gateway InitiativePDE Plugin Development EnvironmentPDF Portable Document FormatPOJO Plain Old Java ObjectRCP Rich-Client-PlattformRTT Refactoring Tool TesterSDK Software-Development-KitSVN SubversionSWT Standard Widget ToolkitUI User InterfaceUML Uni�ed Modeling LanguageURI Uniform Resource Identi�erVCM Versions- und Kon�gurationsmanagement-SystemXML Extensible Markup Language

6

Abbildungsverzeichnis

1.1 Beispielklasse zur Anwendung der Rename-Refaktorisierung . . . . . . . . 121.2 Beispielklasse zur Darstellung von Übersetzungsfehlern bei fehlerhafter Re-

name-Refaktorisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.3 Beispielklasse zur Darstellung von Verhaltensänderungen bei fehlerhafter

Rename-Refaktorisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131.4 JUnit-Testfall zur Aufdeckung von Verhaltensänderungen in der Beispiel-

klasse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3.1 Architektur des Refactoring Tool Testers [25] . . . . . . . . . . . . . . . . . 213.2 Erweiterte Architektur des Refactoring Tool Testers . . . . . . . . . . . . . 233.3 Schema der Testkon�guration . . . . . . . . . . . . . . . . . . . . . . . . . 243.4 Basiskomponenten des Refactoring Tool Testers . . . . . . . . . . . . . . . 263.5 Koordinations-Komponenten des RTT . . . . . . . . . . . . . . . . . . . . 293.6 Schema einer Testklasse mit Testfällen für Refaktorisierungswerkzeuge . . . 313.7 Erweiterungsbeziehungen zwischen Plugins [34] . . . . . . . . . . . . . . . 323.8 Dienstverzeichnis des OSGi-Framework [29] . . . . . . . . . . . . . . . . . . 353.9 Dienstkomponenten-Laufzeitumgebung [17] . . . . . . . . . . . . . . . . . . 36

4.1 Schichten des Refactoring Tool Testers . . . . . . . . . . . . . . . . . . . . 414.2 Übersicht der RTT-Core Komponentenstruktur . . . . . . . . . . . . . . . 434.3 Übersicht der RTT Komponentenstruktur . . . . . . . . . . . . . . . . . . 444.4 Übersicht der RTT Modellelemente . . . . . . . . . . . . . . . . . . . . . . 454.5 Schnittstellen des RTT Modells . . . . . . . . . . . . . . . . . . . . . . . . 474.6 Verarbeitungszustände eines Modellelements . . . . . . . . . . . . . . . . . 484.7 Schnittstellen und Klassen der Testkon�guration . . . . . . . . . . . . . . . 504.8 Schematische Struktur einer XML-Testkon�guration . . . . . . . . . . . . . 514.9 Schematische Struktur einer Komponentenbeschreibung zur Realisierung

einer RTT-Erweiterung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524.10 Erweiterte schematische Struktur einer Komponentenbeschreibung zur Rea-

lisierung einer RTT-Erweiterung . . . . . . . . . . . . . . . . . . . . . . . . 524.11 Ausschnitt einer Plugin-Manifest-Datei mit Komponentenbeschreibungen . 534.12 Schnittstellen zur Realisierung von Aktoren . . . . . . . . . . . . . . . . . 544.13 Hilfsklassen zur Realisierung von Aktoren . . . . . . . . . . . . . . . . . . 554.14 Schnittstelle zur Anbindung eines Repositories . . . . . . . . . . . . . . . . 554.15 Schnittstellen und Klassen zur Realisierung einer Modell-Beobachter-Kompo-

nente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

7

Abbildungsverzeichnis

4.16 Schnittstelle zur Realisierung einer Aktion für die Testergebnisansicht . . . 574.17 Testergebnisansicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584.18 Filter der Testergebnisansicht . . . . . . . . . . . . . . . . . . . . . . . . . 59

B.1 Software Updates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74B.2 Installation und Feature-Auswahl . . . . . . . . . . . . . . . . . . . . . . . 75B.3 Installation abschlieÿen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75B.4 About Eclipse und Installationsdetails . . . . . . . . . . . . . . . . . . . . 76B.5 Installationsdetails . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76B.6 Deinstallation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77B.7 Deinstallation abschlieÿen . . . . . . . . . . . . . . . . . . . . . . . . . . . 77B.8 Erzeugen eines Projektes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78B.9 Erzeugen eines Plugin-Projektes . . . . . . . . . . . . . . . . . . . . . . . . 78B.10 Einstellungen eines Plugin-Projektes . . . . . . . . . . . . . . . . . . . . . 79B.11 Inhalt eines Plugin-Projektes . . . . . . . . . . . . . . . . . . . . . . . . . . 79B.12 Abhängigkeit auf RTT Core Plugin . . . . . . . . . . . . . . . . . . . . . . 80B.13 Test-Klasse erzeugen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80B.14 Informationen der Test-Klasse festlegen . . . . . . . . . . . . . . . . . . . . 81B.15 Import Aktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82B.16 Import eines bestehenden Projektes . . . . . . . . . . . . . . . . . . . . . . 82B.17 Import aus einem Projekt-Archiv . . . . . . . . . . . . . . . . . . . . . . . 83B.18 Projekt mit Repository verknüpfen . . . . . . . . . . . . . . . . . . . . . . 84B.19 SVN Connector Auswahl . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84B.20 Repository Informationen festlegen . . . . . . . . . . . . . . . . . . . . . . 85B.21 Initialer Commit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85B.22 Launch-Kon�guration ö�nen . . . . . . . . . . . . . . . . . . . . . . . . . . 86B.23 Testkon�guration erzeugen . . . . . . . . . . . . . . . . . . . . . . . . . . . 87B.24 Auswahl des Testprojektes . . . . . . . . . . . . . . . . . . . . . . . . . . . 87B.25 Aktor-Kon�guration eines Probanden . . . . . . . . . . . . . . . . . . . . . 88B.26 Hinzufügen von Probanden zur Kon�guration . . . . . . . . . . . . . . . . 89

8

Tabellenverzeichnis

3.1 Kon�gurationselemente der Testkon�guration . . . . . . . . . . . . . . . . 253.2 Annotationen für deklarative Testadapter . . . . . . . . . . . . . . . . . . 29

4.1 Verarbeitungsergebnisse im RTT Modell . . . . . . . . . . . . . . . . . . . 474.2 Verarbeitungszuständen im RTT Modell . . . . . . . . . . . . . . . . . . . 494.3 Kardinalitäten für Referenzen einer Komponenten-Beschreibung . . . . . . 53

5.1 Gegenüberstellung der Werkzeuge ASTGen, SafeRefactor und RTT . . . . 64

A.2 Übersicht der RTT Paketstruktur � Teil 1 . . . . . . . . . . . . . . . . . . 70A.4 Übersicht der RTT Paketstruktur � Teil 2 . . . . . . . . . . . . . . . . . . 71A.6 Übersicht der RTT Paketstruktur � Teil 3 . . . . . . . . . . . . . . . . . . 72

9

1 Einleitung

1.1 Motivation

Durch Refaktorisierungen werden bedeutungserhaltende Änderungen an Programmendurchgeführt. Diese verfolgen das Ziel, dem schleichenden Prozess der Verschlechterungder Softwarequalität (�Softwarefäulnis�) entgegen zu wirken und sind damit bei der War-tung von Programmen, zumindest auf lange Sicht, unverzichtbar. [26] Refaktorisierungenliegen in einer verbalen Spezi�kation (u.a. [5]) vor, die es Software-Entwicklern ermöglichtdiese manuell durchzuführen. Gerade die manuelle Durchführung von Refaktorisierungenbirgt Gefahren, so dass bei nicht Beachtung notwendiger Vor- bzw. Nachbedingungen dasbeobachtbare Verhalten von Programmen verändert wird und damit das Ziel einer be-deutungserhaltenden Änderung verfehlt ist. Erschwerend kommt hinzu, dass notwendigeVor- bzw. Nachbedingungen für viele Refaktorisierungen oftmals unvollständig spezi�-ziert oder Aufgrund der Menge von betro�enen Sprachkonstrukten bei der Anwendungnicht manuell zu Überblicken sind. Aus dem zweiten Grund bieten heutige Entwicklungs-umgebungen, wie z.B. Eclipse, NetBeans oder Visual-Studio, Werkzeugunterstützung zurautomatisierten Anwendung von Refaktorisierungen an. Dennoch bleiben viele der exis-tierenden Refaktorisierungswerkzeuge hinter den gestellten Erwartungen, so dass diesenicht korrekt Arbeiten und Fehler einführen [25]. Die Fehler, die dabei durch Anwen-dung von Refaktorisierungswerkzeugen in ein Programm eingeführt werden, reichen vonÜbersetzungsfehlern bis hin zu Verhaltensänderungen, die bestenfalls im Zuge des Testensaufgedeckt werden oder gänzlich unentdeckt bleiben. Um die Qualität von Refaktorisie-rungswerkzeugen zu verbessern, bietet sich, wie für andere Programme auch, das Testenan. Durch das Testen kann zwar nicht die Korrektheit und damit die Abwesenheit vonFehlern bewiesen werden, es können aber Fehler mit vertretbarem Aufwand aufgedecktwerden. Für das Testen von Refaktorisierungswerkzeugen werden Beispielprogramme be-nötigt, die das zu refaktorisierende Sprachkonstrukt enthalten und dieses in einem Kontexteinbetten der mögliche Fehler des Refaktorisierungswerkzeugs aufdeckt. Stellvertretend füreinen solchen Kontext kommen Regressionstests in Frage � das Fehlschlagen eines Test-falls kennzeichnet dann, die durch die Refaktorisierung eingebrachte Verhaltensänderungund damit gleichzeitig den Fehler in der Refaktorisierung. Die syntaktische Überprüfungeines Beispielprogramms erfolgt durch den Übersetzer. Die Regressionstests übernehmenim Anschluss die semantische Überprüfung und stellen damit das unveränderte beobacht-bare Verhalten sicher. Die manuelle Anwendung der beschriebenen Testschritte ist relativaufwendig und fehleranfällig. Insbesondere die Generierung repräsentativer Beispielpro-gramme bzw. notwendiger Regressionstests stellen die Tester vor eine schwierige Aufgabe,

10

1 Einleitung

so dass viele verbleibende Fehler die Folge sind. Abhilfe kann das automatisierte Testenvon Refaktorisierungswerkzeugen scha�en. [25]

Die Idee des automatisierten Testens von Refaktorisierungswerkzeugen ist nicht neu. Esexistieren Testwerkzeuge [2][24] zum automatisierten Testen von Refaktorisierungswerk-zeugen, welche bereits erfolgreich Fehler in den Eclipse- und NetBeans-eigenen Refak-torisierungswerkzeugen nachgewiesen haben. Eine Abgrenzung der vorliegenden Arbeitzu diesen erfolgt im Unterkapitel 5.2. Des Weiteren ist parallel zu dieser Arbeit eineUntersuchung der Eclipse-eigenen Refaktorisierungen mit Hilfe des, in dieser Arbeit im-plementierten, Refactoring Tool Testers [9] gestartet worden.

1.2 Problemstellung

Wie bereits im Unterkapitel 1.1 angedeutet sind viele Refaktorisierungswerkzeuge fehler-haft und erfüllen damit nicht die an Programmierwerkzeuge gestellten Qualitätsansprüche.Dies liegt vor allem daran, dass die spezi�zierten Refaktorisierungen Lücken aufweisen,wie z.B. die unvollständige Beschreibung anzuwendender Schritte oder notwendiger Vor-und Nachbedingungen. Diese Versäumnisse sind nur bedingt auf die Nachlässigkeit derAutoren zurückzuführen � fällt es doch schwer selbst einfache Refaktorisierung vollstän-dig zu überblicken. Gerade die, aus der Kombination und Variation einer Refaktorisierungentstehende, Menge aller möglicherweise betro�enen Sprachkonstrukte übersteigt in vielenFällen ein überschaubares Maÿ und sprengt damit den Rahmen einer solchen Beschrei-bung. Somit macht die korrekte und vollständige Spezi�kation von Refaktorisierungenerst im Rahmen der Entwicklung eines dazugehörigen Refaktorisierungswerkzeugs Sinnund kann durch Einsatz eines Testwerkzeugs dokumentiert werden.[25]

Im Folgenden wird, zum Zweck der Problemdarstellung, an einem Beispiel ein möglichesFehlschlagen der Rename-Refaktorisierung angeführt. Dabei werden die Arten von einge-brachten Fehlern aufgezeigt und dargestellt wie diese aufgedeckt werden können.

Beispiel Entscheidet sich ein Benutzer, im Beispielprogramm aus Abbildung 1.1, in-nerhalb der Methode add(int value) einen neuen Bezeichner für die Variable value zuwählen, kann mit Hilfe des Rename-Refaktorisierungswerkzeugs die notwendigen Code-Änderungen vorgenommen werden. Werden dabei, wie beispielsweise in Abbildung 1.2gezeigt, nur die Codezeilen 06 und 07 verändert, die notwendigen Anpassung an derMethodensignatur hingegen vergessen, führt dies zu Syntaxfehlern, die durch den Über-setzer gemeldet werden. Sehr viel unangenehmer stellen sich Verhaltensänderungen dar,die durch ein Refaktorisierungswerkzeug eingebracht werden. Diese bleiben durch denÜbersetzer unentdeckt und werden bestenfalls im Zuge des Testens aufgedeckt oder blei-ben gänzlich unentdeckt. Zu einer Verhaltensänderung, des Beispielprogramms aus Abbil-dung 1.1, kann es kommen, wenn in den Nachbedingungen des Refaktorisierungswerkzeugsvergessen wurde auf schon existierende Programmelemente mit gleichen Bezeichnern zu

11

1 Einleitung

1 c l a s s Counter {2

3 pr i va t e i n t _value = 0 ;4

5 pub l i c void add ( i n t va lue ) {6 _value = _value + value ;7 System . out . p r i n t l n ( va lue ) ;8 }9

10 pub l i c i n t get ( ) {11 r e turn _value ;12 }13 }

Abbildung 1.1: Beispielklasse zur Anwendung der Rename-Refaktorisierung

1 c l a s s Counter {2

3 pr i va t e i n t _value = 0 ;4

5 pub l i c void add ( i n t va lue ) {6 _value = _value + renamedValue ;7 System . out . p r i n t l n ( renamedValue ) ;8 }9

10 pub l i c i n t get ( ) {11 r e turn _value ;12 }13 }

Abbildung 1.2: Beispielklasse zur Darstellung von Übersetzungsfehlern bei fehlerhafterRename-Refaktorisierung

12

1 Einleitung

1 c l a s s Counter {2

3 pr i va t e i n t _value = 0 ;4

5 pub l i c void add ( i n t _value ) {6 _value = _value + _value ;7 System . out . p r i n t l n (_value ) ;8 }9

10 pub l i c i n t get ( ) {11 r e turn _value ;12 }13 }

Abbildung 1.3: Beispielklasse zur Darstellung von Verhaltensänderungen bei fehlerhafterRename-Refaktorisierung

1 pub l i c c l a s s TestCounter {2

3 @Test4 pub l i c void testAdd ( ) {5 Counter counter = new Counter ( ) ;6 counter . add ( 8 1 5 ) ;7 a s s e r tEqua l s (815 , counter . get ( ) ) ;8 }

Abbildung 1.4: JUnit-Testfall zur Aufdeckung von Verhaltensänderungen in der Beispiel-klasse

prüfen. Wird durch den Benutzer des Refaktorisierungswerkzeugs die Umbenennung desBezeichners value, innerhalb der Methode add(int value), auf _value gefordert, sollte einkorrekt implementiertes Rename-Refaktorisierungswerkzeug dies ablehnen. Wird die Än-derung hingegen, wie in Abbildung 1.3 dargestellt, durchgeführt, kommt es zu der bereitserwähnten Verhaltensänderung. Durch Anwendung eines eventuell vorhandenen Regres-sionstests à la �JUnit� kann die eingebrachte Verhaltensänderung aufgedeckt werden, wiein Abbildung 1.4 dargestellt. Dieser würde nach eingebrachter Änderung fehlschlagen.

Aufgabenstellung Das Hauptaugenmerk dieser Arbeit liegt in der Entwicklung ei-nes Eclipse-Plugins zum automatisierten Testen von Refaktorisierungswerkzeugen. Dabeisoll ein zu testendes Refaktorisierungswerkzeug auf mögliche Programmelemente einesProbanden-Projektes angewendet werden und durch Anwendung vorhandener Testfällegeprüft werden, ob das Programm immer noch dieselbe Bedeutung hat.

13

1 Einleitung

1.3 Aufbau der Arbeit

Nachdem im ersten Kapitel auf die Motivation der Arbeit eingegangen und Anhand vonBeispielen die Problemstellung erörtert wurde, folgt im Kapitel 2 die De�nition von indieser Arbeit verwendeten Begri�en. Das Kapitel 3 stellt die Vorgehensweise, Architekturund Konzepte der Lösung vor. Des Weiteren werden die notwendigen Grundlagen zumVerständnis der Implementierung vermittelt. Im Kapitel 4 wird die auf dem Lösungs-ansatz basierende Umsetzung beschrieben. Insbesondere wird in diesem Kapitel auf dieOrganisation, Struktur und die bereitgestellten Möglichkeiten zur Erweiterung der Imple-mentierung eingegangen. Daneben werden die Mittel zur Analyse vor Fehlern präsentiert.Im folgenden Kapitel 5 werden die Ergebnisse der Arbeit diskutiert und mit verwandtenArbeiten verglichen. Das Kapitel 6 schlieÿt die Arbeit mit einer Zusammenfassung undeinem Fazit, gefolgt von einem Ausblick, ab.

14

2 Begri�sde�nitionen

Refaktorisierung Refaktorisierungen sind Modi�kationen am Programmcode mit demZiel der Verbesserung der Softwarestruktur, ohne deren Bedeutung zu ändern. Sie wirkendamit dem schleichenden Prozess der Verschlechterung der Softwarequalität (�Software-fäulnis�) entgegen und sind bei der Wartung von Programmen, zumindest auf lange Sicht,unverzichtbar. Eine Refaktorisierung ist fehlerhaft, wenn der Code nach Durchführungein anderes Verhalten aufweist. Die Bedeutungserhaltung des Codes ist somit die zentraleAnforderung an Refaktorisierungen. [26]

Flower de�niert eine Refaktorisierung als Abfolge von Schritten, die die interne Struktureines Programms modi�zieren, ohne das beobachtbare Verhalten zu verändern [5].

�A series of small steps, each of which changes the program's internal structurewithout changing its external behavior [5].�

Unterschieden werden Refaktorisierung von Refaktorisierungswerkzeugen; eine Refakto-risierung bezeichnet das Muster, also die Vorgehensweise, das Refaktorisierungswerkzeughingegen ein Programm, das die Refaktorisierung automatisiert vornehmen kann. [25]

Refaktorisierungswerkzeug Refaktorisierungswerkzeug sind Programme, die eine Re-faktorisierung automatisiert vornehmen können. Für die automatisierte Anwendung einerRefaktorisierung wählt ein Benutzer, neben dem Refaktorisierungswerkzeug, die zu re-faktorisierenden Programmelemente bzw. Parameter aus. Nach Überprüfung aller Vor-und Nachbedingungen wendet das Refaktorisierungswerkzeug die Refaktorisierung mitden festgelegten Parametern an und transformiert alle im Programm betro�enen Sprach-konstrukte. Für den Fall, dass mindestens eine Vor- bzw. Nachbedingungen nicht erfülltist, wird die Refaktorisierung nicht ausgeführt und entsprechende Fehlermeldungen ausge-geben. In den Vorbedingungen werden die angegebenen Eingabeparameter auf ihre Kor-rektheit überprüft; die Nachbedingungen überprüfen, nach Berechnung der betro�enenSprachkonstrukte, ob die geplanten Änderungen gültig und damit bedeutungserhaltendensind. Insbesondere werden Nachbedingungen nicht nach Ausführung einer Refaktorisie-rung validiert, sondern nach Berechnung der betro�enen Sprachkonstrukte.

Modultest Der Begri� Modultest beschreibt die kleinste eigenständig zu testende Pro-grammeinheit � das Modul. In der objektorientierten Programmierung sind diese Pro-grammeinheiten Methoden, Klassen oder im Extremfall ganze Pakete [26]. Zu jeder Pro-grammeinheit wird ein Modultest spezi�ziert, der einen Testfall umsetzt. Da Klassen, in

15

2 Begri�sde�nitionen

der objektorientierten Programmierung, in der Regel aus einem Ge�echt von Objektenbestehen, kommen zur Isolation von zu testenden Einheiten Mock-Objekte zum Einsatz.Diese Stellvertreter ahmen dann das Verhalten des �realen� Objektes nach und stellen da-mit die Isolation sicher. [20] Für das automatisierte Testen von Programmen stehen, fürModultests, Testwerkzeuge bereit. Bekannte Vertreter sind JUnit, NUnit oder CPPUnit,die zur Familie der xUnit-Frameworks1 gehören. Zu den typisch im Modultest eingesetztenTestverfahren zählt der Regressionstest [6]. Des Weiteren existieren diverse Testwerkzeugezur Analyse der Testabdeckung, wie z.B. Cobertura, Jester oder Quilt in Verbindung mitJUnit.

Regressionstest Der Regressionstest gehört zu den dynamischen Testverfahren undsetzt damit die Ausführbarkeit des zu testenden Programms voraus. Gemeinsam habenalle dynamischen Testverfahren, dass das zu testende Programm zusammen mit den fest-gelegten systematischen Eingabedaten (Testfällen) ausgeführt wird. Für jeden Testfallwerden neben den Eingabedaten auch die erwarteten Ausgabedaten angegeben. Die durcheinen Testlauf erzeugten Ausgabedaten werden mit den jeweils erwarteten Daten vergli-chen. Bei Abweichungen liegt ein Fehler vor. Für das Testverfahren, des Regressionstest,werden alle oder eine Teilmenge von existierenden Testfällen, nach Durchführung vonModi�kationen, wiederholt, um Folgefehler oder Seitene�ekte in bereits getesteten Pro-grammteilen auszuschlieÿen. Solche Modi�kationen entstehen in der Regel durch P�ege,Änderung und Korrektur von Programmen. Aufgrund des Wiederholungscharakters undder Häu�gkeit dieser Wiederholungen werden Regressionstests sinnvollerweise automati-siert durchgeführt. [14][6]

Proband Im Kontext des Refactoring Tool Testers stellen Probanden Eingabe-Projektedar. Dabei sind Probanden autonome Beispielprogramme, die zu refaktorisierenden Sprach-konstrukte enthalten und diese in einen Kontext einbetten, der mögliche Fehler des Re-faktorisierungswerkzeugs aufdeckt. Analog zu der medizinischen Verwendung des Begri�sProband, kann dieser, im technischen Kontext des automatisierten Testens von Refakto-risierungen, als Versuchsperson (engl. test subject) bzw. -kandidat aufgefasst werden, andem eine Refaktorisierung erprobt wird. [25]

Orakel Zum Nachweisen von Fehlern in Refaktorisierungswerkzeugen kommt das soge-nannte Back-to-Back-Testverfahren zum Einsatz [25]. Dabei werden die Ausgaben von ver-schiedenen Versionen von Programmen miteinander verglichen. Für den Anwendungsfalldes Refactoring Tool Testers, werden die Ausgaben des Original-Programms, mit denennach Refaktorisierung, verglichen. Da das Back-to-Back-Testverfahren zu den dynami-schen Testverfahren gehört, ist die Ausführbarkeit des Probanden, vor und nach Refakto-risierung, vorausgesetzt. [14] Der beschriebenen Problemstellung widmen sich Orakel imKontext des Refactoring Tool Tester. Das Testwerkzeug stellt durch Anfragen an Orakel

1Der vorangestellte Buchstabe x kennzeichnet dabei die eingesetzte Programmiersprache.

16

2 Begri�sde�nitionen

den Zustand (übersetzbar bzw. unverändertes beobachtbares Verhalten) eines Probandenfest.

Repository Repositories sind im Wesentlichen Archive (beispielsweise CVS oder SVN),in denen Projekte verwaltet werden [25]. Für den Refactoring Tool Testers werden vor-zugsweise Probanden hinterlegt und zum Zwecken des automatisierten Testens von Re-faktorisierungswerkzeugen entnommen. Durch die Repositories ist gewährleistet, dass einezuvor erzeugte Testkonstellation wiederhergestellt werden kann.

Komponentensoftware Unter dem Begri� der komponentenorientierten bzw. kompo-nentenbasierten Softwareentwicklung versteht man die Entwicklung von Softwaresyste-men durch Zusammensetzen von bereits vorgefertigten, getesteten und wiederverwend-baren Softwarekomponenten (engl. Software Components) [28]. Die Motivation hinterder komponentenorientierten Softwareentwicklung liegt darin, dass die Erstellung kom-plexer Anwendungen zu niedrigeren Kosten bei hoher Qualität und innerhalb geringereEntwicklungszeiten ermöglicht werden soll. Gewährleistet wird dies vor allem dadurch,dass die Software aus bereits vorgefertigten und vollständig getesteten Komponenten zu-sammengesetzt wird. Zwar brachte bereits die Einführung der objektorientierten Soft-wareentwicklung groÿe Fortschritte in der Wiederverwendung von Software, konnte aberletztendlich die Wiederverwendung in der Masse von Anwendungen nur eingeschränktfossieren. Heute bildet die objektorientierte Softwareentwicklung die Grundlage für diekomponentenorientierte Softwareentwicklung (engl. component-based development) unddamit für Komponentensoftware, die letztendlich das Produkt der komponentenorientierteSoftwareentwicklung ist [7].

Komponentenmodell Damit Komponenten die wichtigsten Anforderungen, wie z.B.Interoperabilität, Plattform- und Hersteller-Unabhängigkeit oder Wiederverwendbarkeit,erfüllen, müssen diese nach Standards entwickelt werden. Im Kontext komponentenorien-tierten Entwicklung werden diese Standards durch Komponentenmodelle festgelegt. EinKomponentenmodell gibt die Architektur, zu diesem Modell, konformer Komponentenvor. Die De�nition eines Komponentenmodells gliedert sich in der Festlegung folgenderdrei Teilbereiche [12]:

• Festlegung der Semantik � welche Bedeutung haben Komponenten und wie stellensie sich im Modell dar,

• Festlegung der Syntax � wie werden sie repräsentiert und erzeugt,

• Festlegung der Komposition � wie werden Komponenten verbunden bzw. zusam-mengefügt.

Damit Komponenten auch ausgeführt werden können, muss eine Komponentenmodell-Implementierung bereitgestellt werden. Diese Ausführungsumgebung wird durch Frame-works in Applikationservern, Containern oder auch Plattformen realisiert. Es existieren

17

2 Begri�sde�nitionen

eine ganze Reihe von Komponentenmodellen, die eine Teilmenge der notwendigen An-forderungen für Softwarekomponenten de�nieren, dazu gehören beispielsweise JavaBeans,COM/DCOM, CORBA oder auch OSGi. [11]

Framework Ein Framework liefert ein Programmgerüst, also eine wiederverwendbareSchablone, für das Erstellen bestimmter Klassen von Softwaresystemen. Dabei de�niertdas Framework die Architektur und die erlaubten Kollaborationen zwischen Komponen-ten. Durch Vervollständigung des Frameworks können konkrete Softwaresysteme ausge-baut werden. Ein Framework de�niert insbesondere den Kontroll�uss der Anwendung unddie Schnittstellen für die konkreten Klassen, die vom Programmierer erstellt und regis-triert werden müssen. [11] Somit kann ein Framework als Ausführungsumgebung aufge-fasst werden, in der die vom Programmierer bereitgestellten Erweiterungen ausgeführtwerden (Prinzip inversion of control). Auch für die bereits, im Unterkapitel 2, eingeführ-ten Komponentenmodelle existieren Implementierungen in Form von Frameworks, wiez.B. die OSGi Referenzimplementierung Equinox.

18

3 Lösungsansatz

3.1 Vorgehensweise

Wie bereits in der Motivation dieser Arbeit eingeleitet, fallen Refaktorisierungswerkzeugein die Kategorie der Metaprogramme, wie z.B. Übersetzer oder Debugger und weitereProgrammierwerkzeuge. Da sich Fehler in Metaprogrammen vor allem in der Ausführungder von ihnen manipulierten Programme zeigen, sind diese Programme besonders schwerzu Debuggen und zu Testen. Insbesondere das Testen von Refaktorisierungswerkzeugengestaltet sich nicht einfach: Es werden Beispielprogramme benötigt, die das zu refaktori-sierende Sprachkonstrukt enthalten und dieses in einen Kontext einbetten, der möglicheFehler des Refaktorisierungswerkzeugs aufdeckt. Der Lösungsansatz des Refactoring ToolTesters geht daher von der Generierung notwendiger Probanden ab und bedient sich an derVielzahl verfügbarer quello�ener (engl. open-source) Programme. Durch dieses Vorgehenergeben sich gleich zwei Vorteile:

• Zum einen handelt es sich bei den Probanden um reale Anwendungen, die eineVielzahl der von den Anwendern verwendeten Sprachkonstrukten beinhalten unddamit repräsentativ sind,

• zum anderen besitzen viele quello�ene Programme eine hohe Testabdeckung (inForm von JUnit-Testfällen), die zur semantischen Prüfung herangezogen werdenkann.

Aus diesen Gegebenheiten vereinfacht sich das automatisierte Testen von Refaktorisie-rungswerkzeugen, denn es können die in der integrierten Entwicklungsumgebung vorhan-denen Mittel zur Validierung einer Refaktorisierung zu Hilfe genommen werden � diesedienen dann dem Testwerkzeug als Orakel. Dem entsprechend übernimmt der Überset-zer die syntaktische Überprüfung eines Probanden. Die Ausführung der Regressionstestsübernimmt im Anschluss die semantische Überprüfung und stellt damit das unverändertebeobachtbare Verhalten sicher, das de�nitionsgemäÿ die Korrektheit einer Refaktorisie-rung quali�ziert. Im Artikel [25] wird der vereinfachte Algorithmus des automatischenTestwerkzeugs vorgestellt, der in der Grundidee mit dem in dieser Arbeit implementier-ten Refactoring Tool Tester übereinstimmt. Der dort beschriebene Ablauf nutzt die bereitseingeleiteten Sachverhalte in den folgenden Zusammenhängen:

Eingabe Beispielprogramme (vorzugsweise quello�ene Programme), die die zu refaktori-sierenden Sprachkonstrukte enthalten und gut durch Tests abgedeckt sind, werdenals Probanden aus einem Repository entnommen. Das Repository dient dabei dem

19

3 Lösungsansatz

Zweck der Verwaltung von Probanden gemeinsam mit ihren Kon�gurationsinforma-tionen, wie z.B. die von Testläufen ausgeschlossenen Klassen.

Verarbeitung Das Testwerkzeug wendet ein Refaktorisierungswerkzeug, indirekt übereinen zuvor bereitgestellten Testadapter, auf allen anwendbaren1 Programmstellenan und prüft nach Refaktorisierung mittels der o.g. Orakel, ob alle Änderungen be-deutungserhaltend sind. Die Testadapter stellen dabei die Kopplung zwischen Refak-torisierungswerkzeug und Testwerkzeug her und sind dafür verantwortlich notwen-dige Parameter für die Refaktorisierung festzulegen. Die Bereitstellung von Testad-aptern erfolgt über die von Eclipse zur Verfügung gestellten Plugin-Mechanismen,so dass diese Komponenten den Refactoring Tool Tester erweitern. Die zugehörigeStatus-Meldung, zum Erfolg oder Misserfolg einer Refaktorisierung, wird nach jederAnwendung eines Refaktorisierungswerkzeugs über das Testwerkzeug erzeugt undkann so angezeigt oder weiterverarbeitet werden. Nach Anwendung einer Refak-torisierung werden im Abschluss jedes Verarbeitungsschritts alle Änderungen, vorAnwendung der nächsten Refaktorisierung, rückgängig gemacht, so dass für jedeRefaktorisierung die gleichen Ausgangsbedingungen herrschen.

Ausgabe Für den Benutzer des automatischen Testwerkzeugs werden die Status-Mel-dungen aufbereitet, die im Anschluss aller Testläufe zur Fehleranalyse herangezogenwerden können. Insbesondere beinhaltet die Ausgabe die Refaktorisierungsbeschrei-bung und die dazugehörigen Status-Meldungen der Orakel. Die Refaktorisierungsbe-schreibung beinhaltet die notwendigen Informationen zum Refaktorisierungswerk-zeug und alle bei der Refaktorisierung verwendete Parameter.

Wie angedeutet erfolgt die Durchführung von automatisierten Refaktorisierungen alsBatchprozess, der dem klassischen Eingabe-Verarbeitung-Ausgabe-Modell unterliegt. Be-vor die Beschreibung des in dieser Arbeit implementierten Refactoring Tool Testers fortge-führt wird, folgt in Abbildung 3.1 zum Zweck der Gegenüberstellung die im Artikel [25] be-schriebene Architektur. Wie in Abbildung 3.1 dargestellt, sind das Probanden-Repositoryund die Orakel Bestandteile des Testwerkzeugs. Die Testadapter, die Probanden und daszu testende Refaktorisierungswerkzeug werden vom Benutzer des Testwerkzeugs vor derAnwendung eines Testlaufs bereitgestellt. Typischerweise können die Probanden nach Be-reitstellung unverändert für verschiedene Testläufe wiederverwendet werden. An dem zutestenden Refaktorisierungswerkzeug sind keinerlei Anpassungen notwendig, die Testad-apter stellen die notwendige Kopplung zum Testwerkzeug her. Der Aufwand für das Testeneines konkreten Refaktorisierungswerkzeugs beschränkt sich damit auf das Bereitstellenvon mindestens einem Testadapter � nachdem das Probanden-Repository notwendige Bei-spielprogramme beinhaltet. Insbesondere müssen Tester in der Regel keine Testfälle fürein Refaktorisierungswerkzeug formulieren, da das Refaktorisierungswerkzeug nur indirektgetestet wird und die Testfälle zur Veri�zierung einer bedeutungserhaltenden Änderungzu den Projekten der Probanden gehören. Zur Schnittstelle eines Testadapters gehörtdie Identi�kation anwendbarer Programmstellen, die vom Testwerkzeug für Refaktorisie-

1Dies beinhaltet insbesondere die Überprüfung notwendiger Vor- und Nachbedingungen eines Refakto-risierungswerkzeugs.

20

3 Lösungsansatz

Abbildung 3.1: Architektur des Refactoring Tool Testers [25]

rungen angefordert werden. Die Bestimmung der Programmstellen in den Probanden, andenen eine Refaktorisierung ausgeführt werden kann, kann vorzugsweise durch Ablaufdes abstrakten Syntaxbaums (AST) herausge�ltert werden. Schwieriger gestaltet sich dieAuswahl geeigneter Parameter für ein Refaktorisierungswerkzeug, um tatsächlich Fehleraufzudecken. Insbesondere können für manche Refaktorisierungen nicht alle Kombinatio-nen von Parameterwerten durchprobiert werden, wenn diese potentiell unendlich vieledarstellen, wie z.B. bei der Rename-Refaktorisierung [25]. Für diese Art von Refaktorisie-rungen ist es notwendig Parameter zu wählen, die gezielt Fehler provozieren und damit dieLaufzeit von notwendigen Testläufen begrenzen � womit die Formulierung eines solchenTestadapters im Extremfall des einen Testfalls gleich kommt [25].

Anforderungen Aus den bereits angeführten Ausführungen sind folgende Anforderun-gen, an das umgesetzte Testwerkzeug, abgeleitet worden:

1. Testadapter sind die zentralen Koppelglieder zwischen Refaktorisierungswerkzeugund Testwerkzeug und müssen daher in ihrer Formulierung einfach gestaltet sein, umden Implementierungsaufwand für das Testen eines Refaktorisierungswerkzeugs zuminimieren. Insbesondere sollte das Testwerkzeug Tester bei der Umsetzung wieder-kehrende Aufgaben (im Hinblick auf Testadapter) unterstützen und ggf. Hilfsklassenbereitstellen, die z.B. das Finden und Filtern von anwendbaren Programmstellen fürein Refaktorisierungswerkzeug erleichtern.

2. Da das Durchprobieren aller Kombinationen von Parameterwerten für einige Refak-torisierungswerkzeuge nicht zielführend ist, ist es notwendig, dass das Testwerkzeugden Tester bei der Auswahl von Parameterwerten unterstützt, die es ihm ermögli-chen gezielt Fehler zu provozieren.

3. Probanden-Projekte werden, gemeinsam mit ihren Kon�gurationsinformationen, inRepositories verwaltet und zum Zweck des Testens von Refaktorisierungen entnom-men. Die Verwaltung und Bereitstellung von Testkon�gurationen für Testläufe sindnotwendiger Bestandteil des Testwerkzeugs, so müssen neben den anzuwendenden

21

3 Lösungsansatz

Testadaptern für ein Refaktorisierungswerkzeug, die zu verwendenden Probanden-Projekte ausgewählt und benötigte Parameter festgehalten werden. Insbesonderemuss das Testwerkzeug sicherstellen, dass eine Testkonstellation im Nachhinein re-produzierbar ist.

4. Orakel sind die zentralen Anlaufstellen des Testwerkzeugs und ermöglichen ihmdie indirekte Identi�kation von Fehlern in Refaktorisierungswerkzeugen. Auÿer denbeschriebenen Orakeln zur syntaktischen und semantischen Überprüfung von Pro-banden, die zum Umfang des Testwerkzeugs gehören, sollte der Refactoring ToolTester um weitere erweitert werden können.

5. Dem Benutzer des Testwerkzeugs sind Mittel zur Analyse von Fehlern bereitzustel-len, die ihm die systematische Lokalisierung von Fehlerquellen ermöglichen. Insbe-sondere ist die Anbindung von automatischen Werkzeugen zur Lokalisierung vonFehlerquellen vorzusehen.

3.2 Architektur

Die angeführten Anforderungen, aus dem Unterkapitel 3.1, de�nieren die Rahmenbedin-gungen für die Architektur, des in dieser Arbeit implementierten Refactoring Tool Testers.Insbesondere stellt die zweite Anforderung eine Herausforderung dar. Während sich dieAuswahl von anwendbaren Programmstellen für ein Refaktorisierungswerkzeug eher ein-fach gestaltet (diese können durch Ablauf des abstrakten Syntaxbaum eines Probandenherausge�ltert werden), stellt sich die Auswahl von Parameterwerten, zum Zweck dergezielten Provokation von Fehlern, als schwierig heraus. Zwar ist die gleiche Vorgehens-weise für einfache Anwendungsfälle, wie z.B. für das Rename-Refaktorisierungswerkzeug,möglich, um in Kon�ikt stehende Sprachkonstrukte auszuwählen, aber mit einem zusätzli-chen Laufzeit- und Programmieraufwand verbunden. Müssen zudem Beziehung zwischenProgrammelementen, z.B. zwischen Klassen oder -Hierarchien, ausgedrückt werden, kannder Aufwand schnell Überhand nehmen. Vergleicht man die Auswahl von anwendbarenProgrammstellen mit der Auswahl von Parameterwerten, zum Zweck der gezielten Pro-vokation von Fehlern, stellt man fest, dass beide das Ziel verfolgen eine Menge von Pro-grammstellen zu selektieren. Lediglich die Auswahlkriterien unterscheiden sich. Somit ver-einfacht sich die Problemlösung � in der Bereitstellung von Mechanismen zur Selektionvon Programmstellen in Probanden nach Auswahlkriterien, die durch den Tester einesRefaktorisierungswerkzeugs festzulegen sind.

Abfragesprachen bieten die geforderten Eigenschaften und kommen typischerweise inProgramm-Analysewerkzeugen zum Einsatz, wie z.B. SemmleCode. Den gleichen Ansatzverfolgt der Refactoring Tool Testers zur Erfüllung der ersten und zweiten Anforderung.Hierzu kann durch Einsatz eines Abfragewerkzeugs eine Formalisierung von Testadapternerfolgen. Das Testwerkzeug stellt einen Testadapter bereit, der mittels Introspektion Test-fälle für Refaktorisierungswerkzeuge anwendet � diese Testfälle sind nicht zu verwechseln

22

3 Lösungsansatz

Abbildung 3.2: Erweiterte Architektur des Refactoring Tool Testers

mit denen die zur semantischen Überprüfung angewendet werden und Teil der Proban-den Projekte sind. Damit der spezialisierte Testadapter (Abfragewerkzeug-Testadapter)Testfälle identi�zieren kann, müssen diese gekennzeichnet bzw. annotiert werden. Mitdiesen Mitteln entfällt die Notwendigkeit Testadapter zu implementieren, wenn TesterTestfälle, für das automatisierte Testen von Refaktorisierungswerkzeugen, formulieren.Grundsätzlich stehen beide Implementierungsmöglichkeiten zur Verfügung, so dass dieDesign-Entscheidung dem Tester obliegt. Die bereits angeführten Zusammenhänge wer-den durch die, in Abbildung 3.2 gezeigte, erweiterte Architektur des Refactoring ToolTesters berücksichtigt. Vergleicht man die gezeigte Architektur, aus Abbildung 3.2, mitder bereits vorgestellten, aus Abbildung 3.1, ist festzustellen, dass diese sich lediglich inder beschriebenen Erweiterung unterscheiden.

Zur Erfüllung der dritten Anforderung, aus dem Unterkapitel 3.1, legt der RefactoringTool Tester eine Testkon�guration fest. Diese Testkon�guration gliedert sich in der Kon-�guration von zu verwendenden Probanden und Aktoren � zu den Aktoren zählen Orakelund Testadapter. Die Abbildung 3.3 zeigt die Beziehungen und Elemente innerhalb einerTestkon�guration. In erster Linie dient die gezeigte Testkon�guration der Reproduzierbar-keit einer Testkonstellation und wird sinnvollerweise zu diesem Zweck in einem Repositoryhinterlegt. Wie dargestellt werden Probanden in Repositories verwaltet. Innerhalb einerTestkon�guration können Probanden verschiedener Repositories angefordert werden. Da-für ist in einer Testkon�guration festzuhalten, welchem Repository ein Proband zugehört.Eine weitere notwendige Information kann die Version eines Probanden sein, wenn dieserin einem Proband-Repository verwaltet wird, das mehrere Versionen unterscheidet, wiez.B. ein Versionskontrollsystem. Auch Aktoren besitzen eine Kon�guration, die beispiels-weise angibt welche Ressourcen vom Aktor berücksichtigt bzw. unberücksichtigt bleiben.Die dort angegeben Typen von Ressourcen sind Aktor-spezi�sch und gehören zu einem der

23

3 Lösungsansatz

Abbildung 3.3: Schema der Testkon�guration

zu verwendenden Probanden. Notwendig ist der Ausschluss von Ressourcen beispielsweisefür die semantische Orakel-Kon�guration bei Testfällen (à la JUnit), die in Testsuiten2

verwaltet sind, um die redundante Ausführen zu vermeiden. Um den wiederkehrendenKon�gurationsaufwand für Aktoren, bei der Erzeugung einer neuen Testkon�guration, zuvermeiden, kann eine Aktor-Kon�guration als Standard-Kon�guration im Probanden hin-terlegt werden. Für den Abfragewerkzeug-Testadapter sind weitere Kon�gurationen not-wendig, so unter anderem die anzuwendenden Testfälle für ein Refaktorisierungswerkzeug.Testfälle für Refaktorisierungswerkzeuge werden in einem Testbündel verwaltet, das diesedem Testwerkzeug verfügbar macht. Die Tabelle 3.1 fasst die beschriebenen Bestandteileeiner Testkon�guration zusammen.

2Eine Testsuite ist eine Testfall, der aus anderen Testfällen (ggf. auch Suiten) zusammengesetzt wird.

24

3 Lösungsansatz

Kon�gurationselement BeschreibungProband legt ein zu verwendendes Probanden-Projekt fest.

Bestandteil der Kon�guration ist die URI des Projektes,die neben dem Repository das Projekt eindeutig kenn-zeichnet.

Orakel legt ein zu verwendendes Orakel fest.Bestandteile der Kon�guration sind die eindeutige ID desOrakels und ggf. ausgeschlossener Ressourcen in den Pro-banden-Projekten.

Testadapter legt einen zu verwendenden Testadapter fest.Bestandteile der Kon�guration ist die eindeutige ID desTestadapters. Des Weiteren sind für den Abfragewerkzeug-Testadapter, die ID des zu verwendenden Testbündels unddarin ausgewählter Testfälle festzulegen.

Tabelle 3.1: Kon�gurationselemente der Testkon�guration

Für die angestrebte Umsetzung in der integrierten Entwicklungsumgebung Eclipse könnenTestbündel durch Plugins repräsentiert werden. Die Rolle eines Testbündels kann sowohldurch ein separates Plugin als auch durch das Plugin, des zu testenden Refaktorisierungs-werkzeugs, übernommen werden. Im Bezug auf die Erweiterbarkeit, des Testwerkzeugs,liegt die Aktor-Kon�guration in Verantwortung des jeweiligen Aktors, so dass die Strukturfür weitere Aktoren um neue Kon�gurationselemente erweitert werden kann.

Die vierte Anforderung, der Erweiterbarkeit des Refactoring Tool Testers, wird explizitdurch die integrierte Entwicklungsumgebung (IDE) Eclipse unterstützt. So werden sowohlOrakel als auch Testadapter durch den Eclipse-eigenen Plugin Mechanismus bereitgestellt.Insbesondere übernimmt das unterlagerte Komponenten-Framework (Equinox), für Eclip-se, die notwendige Verwaltung � von der Bereitstellung über das Au�nden bis hin zurInstantiierung � von Komponenten. Die Entwickler von Aktoren müssen lediglich Dienst-komponenten im Sinne des OSGi-Komponentenmodell bereitstellen. Die Schnittstellender o.g. Aktoren de�niert das Testwerkzeug. Da Aktoren, als Komponenten, vorzugsweisezustandslos realisiert werden, existiert zu jedem Aktor im System nur eine Instanz. Diesewerden durch das Komponenten-Framework geliefert und verwaltet. Ein Vorteil, der sichaus der Zustandslosigkeit von Komponenten ergibt, ist, dass auf Synchronisation verzich-tet werden kann, womit die Skalierbarkeit und Wiederverwendbarkeit von Aktoren, auchfür andere Werkzeuge, begünstigt wird. Auf der anderen Seite macht dieses Software-design es notwendig, dass alle Informationen zur Ausführung eines Dienstes mit jedemAufruf übergeben werden.

Zur Erfüllung der letzten Anforderung, aus dem Unterkapitel 3.1, verfeinert der Refacto-ring Tool Testers seine Architektur durch das Model-View-Controller (MVC) Architektur-muster. Die Abbildung 3.4 zeigt die beteiligten Basiskomponenten des Refactoring ToolTesters. Der Anwendungskern übernimmt die Steuerung und Überwachung von Aktoren

25

3 Lösungsansatz

Abbildung 3.4: Basiskomponenten des Refactoring Tool Testers

und damit die Rolle des Controllers. Das Benutzerinterface, der View, wird über Ergebnis-se von Testläufen benachrichtigt, die über den Anwendungskern delegiert werden. Die Er-gebnisse eines Testlaufs sind Aktor-spezi�sch und werden über diesen durch entsprechendeModellelemente repräsentiert. Das gesamte Modell ist hierarchisch aufgebaut, so dass al-le Informationen � von der Sitzung über die Testkon�guration bis hin zum Fehlerbild �bei Benachrichtigung zur Verfügung stehen. Durch die dargestellte Trennung zwischenDarstellungs-, Verarbeitungs- und Datenhaltungsschicht können auf einfache Weise wei-tere Analysewerkzeuge angebunden werden. Dazu registrieren sich Analysewerkzeuge, wiebeispielsweise das Benutzerinterface, für Benachrichtigungen von Modelländerungen beimAnwendungskern. Die notwendigen Mechanismen für die Registrierung werden, wie be-reits bei den Orakel- und Testadapter-Komponenten, durch das Komponenten-Frameworkgeliefert.

3.3 Ablauf von Tests

Wie bereits eingeleitet, benötigt der Refactoring Tool Tester zur Anwendung eines au-tomatisierten Tests, neben den Probanden und den Aktoren, eine Testkon�guration. DieBestandteile der Testkon�guration sind in der Tabelle 3.1 beschrieben. Aus der Test-kon�guration bestimmt der Refactoring Tool Tester die zu verwendenden Aktoren undProbanden. Die Aktoren werden dem Refactoring Tool Tester durch das Komponenten-Framework bereitgestellt. Vorbereitend für einen Testlauf werden die festgelegten Pro-banden durch den Anwendungskern aus ihren Repositories abgerufen. Die so erzeugtenProbanden-Projekte bilden gemeinsammit der Testkon�guration den Initialen-Testkontext,

26

3 Lösungsansatz

der für jeden Aktor instantiiert wird. Nach Instantiierung wird dieser Kontext dem je-weiligen Aktor zur Analyse von Probanden bereitgestellt. Die Analyse bildet damit dieStart- bzw. Initialisierungsphase eines Aktors und wird für einen Testlauf einmalig ausge-führt. Welche vorbereitenden Maÿnahmen in der Initialisierungsphase notwendig sind, istAktor-spezi�sch � so wird beispielsweise ein Testadapter zu refaktorisierende Programm-stellen, das semantische Orakel hingegen anzuwendende Testfälle, Suchen und Filtern.Andere Aktoren könnten auf die Initialisierungsphase auch gänzlich verzichten. Auÿerder beschriebenen Initialisierungsphase unterscheiden Aktoren die Phasen Anwendungund Finalisierung. Die eigentlichen Arbeiten werden vom Aktor in der Anwendungsphaseübernommen. Die Finalisierung bildet das Gegenstück zur Initialisierung und wird nachAbschluss eines Testlaufs eingeleitet, um ggf. zu bereinigende Ressourcen aufzuräumen.

Da Aktoren, als Komponenten, vorzugsweise zustandslos realisiert werden, können Zwi-schenergebnisse zu durchgeführten Aktionen zur späteren Weiterverarbeitung im Test-kontext des jeweiligen Aktors hinterlegt werden. Somit beinhaltet der Kontext alle Infor-mationen, die für die Durchführung eines Aktor-Dienstes notwendig sind, und dient alsParameter-Objekt. Auf der anderen Seite stellt der Kontext, als Modellelement, Tester-gebnisse bereit � Aktoren können diese an den Kontext anhängen. Das Gesamtergebniseines Testlaufs wird über eine Sitzung repräsentiert und beinhaltet alle erzeugten Testkon-texte mit den angehängten Testergebnissen. Da der Anwendungskern keinerlei Kenntnisüber den Inhalt der im Kontext verwalteten Informationen hat, wird ihm das Ergebnisder Verarbeitung über den Status des Testkontextes bereitgestellt. Dabei setzt sich derStatus eines Kontextes aus den einzelnen Testergebnissen zusammen. Aus der Summealler Status wird der Status eines Testlaufs bestimmt.

Da aus Sicht des Controllers eine Gleichbehandlung von Aktoren, also Orakel und Test-adapter, erfolgt, kann dieser die erforderlichen Testschritte nicht im Voraus berechnen.Weswegen der Anwendungskern es den Aktoren überlässt ihm mitzuteilen, wenn diese ihreArbeiten abgeschlossen haben. Als Schnittstelle, zwischen Aktoren und Controller, dienthierzu wieder der Testkontext. Die Testabfolge gliedert sich in die Schritte, Überprüfungvon Vorbedingungen, Anwendung eines Testadapters und abschlieÿende Überprüfung vonNachbedingungen. Die Einhaltung von Vor- und Nachbedingungen, für einen Test, werdendurch die syntaktischen und semantischen Überprüfungen sichergestellt. Weist eine derÜberprüfung auf Fehler hin, kann die Reaktion der Aktoren unterschiedlich sein. WährendOrakel in der Regel die Ausführung nach dem ersten gefundenen Fehler abbrechen, werdenTestadapter zum nächsten Testszenario wechseln.

Zur syntaktischen Überprüfung eines Probanden wendet der Anwendungskern alle syn-taktischen Orakel hintereinander an. Im Anschluss führt der Anwendungskern alle seman-tischen Überprüfung mit Hilfe der dafür vorgesehenen Orakel durch. Die resultierendenTestergebnisse (Modellelemente) werden dem Testkontext angehängt. Bei erfolgreichemStatus des Testkontextes, d.h. in diesem Fall erfolgreicher syntaktischer und semantischerÜberprüfung, wird ein Testadapter ausgewählt und so ein Refaktorisierungswerkzeug an-gewendet. Für den Fall, dass das Refaktorisierungswerkzeug angewendet werden konn-te, werden im Anschluss wieder alle Probanden einer syntaktischen und semantischen

27

3 Lösungsansatz

Analyse unterzogen und die Testergebnisse im Testkontext hinterlegt. Auch die Testad-apter haben die Möglichkeit Informationen über das Refaktorisierungswerkzeug im Kon-text zu hinterlegen, so z.B. die Beschreibung einer Refaktorisierung. Bevor zum nächstenRefaktorisierungswerkzeug gewechselt wird, werden alle Änderungen an den Probandenzurückgenommen, so dass für jede Refaktorisierung die gleichen Ausgangsbedingungenherrschen.

3.4 Steuerung und Überwachung von Aktoren

Der beschriebene Testablauf, aus dem Unterkapitel 3.3, verdeutlicht, dass für die Steue-rung und Überwachung von Aktoren, durch den Anwendungskern, unterschiedliche Kon-troll�üsse berücksichtigt werden müssen. Während alle Orakel hintereinander ausgeführtwerden, wählt der Anwendungskern lediglich einen aktiven Testadapter zur Anwendungvon Testszenarien aus.

Damit der Anwendungskern den unterschiedlichen Anforderungen zur Steuerung undÜberwachen von Aktoren gerecht wird, separiert er diese Aufgaben in eigene Kompo-nenten � Test-Runner. Der Anwendungskern, als Controller, delegiert seine Steuer- undÜberwachungsaufgaben an diese Komponenten und erhält von ihnen die erforderlichenStatusmeldungen. Im Framework des Refactoring Tool Testers stellen Test-Runner ledig-lich weitere Aktoren dar, die aus den bereits eingeführten Aktoren (Orakel und Testad-apter) zusammengefügt werden. Die Eigenschaft, das Aktoren hierarchisch aufgebaut seinkönnen3, liefert das Komponentenmodell. Das Testwerkzeug berücksichtigt diese Zusam-menhänge in seinem Modell, in dem auch Testergebnisse (Modellelemente) hierarchischaufgebaut werden. Die Abbildung 3.5 zeigt die beteiligten Komponenten zusammen mit ih-ren Kompositionen. Der Anwendungskern verwendet den Refaktorisierungs-Test-Runnerzur Steuerung und Überwachung des Gesamtablaufs. Dieser setzt sich zusammen ausTestadaptern und Orakel-Runner. Der Refaktorisierungs-Test-Runner wendet einen Test-adapter solange an, bis dieser ihm zurückmeldet, dass alle Refaktorisierungen für einWerkzeug durchgeführt wurden. Danach wechselt er zum nächsten Testadapter. Vor undnach der Anwendung eines Testadapters weist der Refaktorisierungs-Test-Runner denOrakel-Runner an, die syntaktischen und semantischen Überprüfungen durchzuführen.Der Orakel-Runner setzt sich aus den kon�gurierten Orakeln zusammen. Da die Aus-führbarkeit der Probanden vor der semantischen Überprüfungen gewährleistet sein muss,wendet der Orakel-Runner zuerst die syntaktischen und danach die semantischen Orakelan.

3d.h. unter anderem können neue Aktoren durch (rekursive) Komposition von bereits vorhandenenrealisiert werden

28

3 Lösungsansatz

Abbildung 3.5: Koordinations-Komponenten des RTT

3.5 Testfälle für Refaktorisierungswerkzeuge

Wie bereits im Unterkapitel 3.2 angedeutet, stellt das Testwerkzeug deklarative Testadap-ter bereit, die mittels Introspektion Testfälle für Refaktorisierungswerkzeuge anwenden.Einer dieser Testadapter ist der Abfragewerkzeug-Testadapter, der es Testern ermöglicht,durch Abfragen an Probanden zu refaktorisierende Programmstellen auszuwählen. Damitdeklarative Testadapter anzuwendende Testfälle für Refaktorisierungswerkzeuge identi�-zieren können, sind diese zu markieren bzw. annotieren. Für deklarative Testadapter sindim Framework des Testwerkzeug nachfolgende Annotationen festgelegt:

Annotation Programmelement Bedeutung@Test Ö�entliche Methode Markiert einen Testfall und spezi�ziert

ggf. die Abfrage zur Selektion der Test-eingaben

@TestParam Methoden-Parameter Markiert einen Platzhalter für eine Variableaus der spezi�zierten Abfrage

@TestSession Feld Markiert einen Platzhalter zur Anforderungvon Sitzungsinformationen

Tabelle 3.2: Annotationen für deklarative Testadapter

Die Tabelle 3.2 zeigt die vorgesehenen Annotationen mit den für diese anwendbaren Pro-grammelemente. So kennzeichnet beispielsweise die Annotation @Test einen Testfall fürein Refaktorisierungswerkzeug an einer ö�entlichen Methode. Ob die annotierte Methodedem Besitzerbereich (engl. scope) der Klasse oder der Instanz zugeordnet wird, ist demTester bei der Spezi�kation seines Testfalls überlassen. Ist ein Testfall im Besitzerbereichder Instanz de�niert, wird vor Anwendung dieses Testfalls eine neue Instanz der zuge-hörigen Testklasse erzeugt. Somit wird jedem Testfall eine eigene Instanz zugeordnet, in

29

3 Lösungsansatz

der dieser, isoliert von den anderen Testfällen, Zustandsinformationen ablegen kann. DesWeiteren beinhaltet die Annotation @Test die Möglichkeit zur Deklaration einer Abfragein textueller Form. Die Syntax ist durch den ausführenden Abfragewerkzeug-Testadaptervorgegeben. Analog zur Annotation @Test markiert die Annotation @TestSession einFeld innerhalb einer Klasse. Diese beinhaltet zur Laufzeit Sitzungsinformationen zumTestlauf, so z.B. die Probanden-Projekte oder Testkon�guration. Die Belegung der Instanzdes Feldes wird durch das Framework, vor der Anwendung eines Testfalls, übernommen,so dass durch den Tester keinerlei Initialisierung vorgenommen werden muss. Insbesonde-re besitzt die Testklasse keine direkt Abhängigkeit auf die zu instantiierende Testsitzungbzw. deren Implementierung, da diese Abhängigkeit durch das Framework injiziert (engl.dependency injection) wird. Dennoch wird der Datentyp des Feldes durch das Frame-work bzw. dem ausführenden Testadapter implizit vorgegeben und ist bei der Deklarationzu beachten. Auch bei annotierten Feldern ist der Besitzerbereich, Instanz oder Klas-se, durch den Tester frei wählbar. Während die Annotationen @Test und @TestSessionauch für andere deklarative Testadapter, als den Abfragewerkzeug-Testadapter, Verwen-dung �nden, ist die Annotation @TestParam speziell für diesen ausgelegt. Die Annotation@TestParam bindet Variablen einer Abfrage, in einer vorgegebenen Abfragesprache, anein Methoden-Argument. Dazu de�niert der Tester in der Annotation den Namen derzu bindenden Variable, die durch die Abfrage de�niert ist. Der Datentyp der Variableist durch den ausführenden Testadapter, mit dem verwendeten Modell zur Repräsenta-tion von Programmstellen, vorgegeben. Die Tupel, der aus der Abfrage resultierendenErgebnismenge, werden über die deklarierten Methoden-Argumente bereitgestellt.

Allein das Annotieren eines Testfalls reicht jedoch noch nicht aus, um ein Refaktori-sierungswerkzeug automatisiert anzuwenden. Damit das Framework, des Testwerkzeugs,ein Refaktorisierungswerkzeug anwenden kann, muss der Testfall eine Refaktorisierungs-beschreibung zurückliefern. Diese beinhaltet neben dem Refaktorisierungswerkzeug, diezu refaktorisierenden Programmelemente und die gewählten Parameterwerte. Auch ist esnotwendig, dass ein Tester die Möglichkeit hat in der Ergebnismenge seiner Abfrage zu na-vigieren, um beispielsweise festzulegen wann zum nächsten Tupel gewechselt wird. Womitein Tester eine zu refaktorisierende Programmstelle für unterschiedliche Refaktorisierungs-Szenarien nutzen kann. Aus der Sicht des Testwerkzeugs zerfallen Testfällen in eine Mengevon Testschritten. Jeder Testschritt umfasst dann eine Refaktorisierungsbeschreibung unddie dazugehörige Kontroll�ussanweisung. In der Umsetzung des Refactoring Tool Testerist der Rückgabewert eines Testfalls als TestProcedureStep de�niert. Die Abbildung 3.6zeigt das Schema einer Testklasse zur De�nition von Testfällen für Refaktorisierungswerk-zeuge.

Durch die hier vorgestellten Annotationen können Testfälle für Refaktorisierungswerk-zeuge markiert und somit durch einen deklarativen Testadapter identi�ziert werden. DasFramework macht dabei keinerlei Vorgaben bezüglich des Aufbaus bzw. der Struktur vonTestfällen. Sowohl die Namensgebung, Vererbungshierarchie als auch die Beziehungen zwi-schen Testklassen sind frei wählbar. Bei der Suche von Testfällen muss das Testwerkzeugdie nachfolgenden Aspekte berücksichtigen:

30

3 Lösungsansatz

1 c l a s s MyTestclass2 {3 @TestSess ion4 pr i va t e Te s tC l i en tSe s s i on s e s s i o n ;5

6 @Test ( )7 TestProcedureStep myTestCase ( )8 {9 Refac to r ing r e f a c t o r i n g = . . .

10 . . .11 r e turn TestProcedureStep . c r e a t e ( r e f a c t o r i n g , FlowDecis ion .NEXT) ;12 }13 . . .14 }

Abbildung 3.6: Schema einer Testklasse mit Testfällen für Refaktorisierungswerkzeuge

• Testfälle müssen für das Framework des Refactoring Tool Testers zugreifbar sein,d.h. sowohl die Testklasse als auch die annotierten Methoden.

• Die Testklasse, die zur Ausführung von Testfällen instantiiert wird, muss über denStandard-Konstruktor instantiierbar sein.

• Testfälle können abstrakt bzw. in abstrakten Testklassen oder Schnittstellen dekla-riert sein � zur Ausführung werden dann die konkreten Subklassen herangezogen.

3.6 Grundlagen und Hilfsmittel

Eclipse Eclipse, als integrierte Entwicklungsumgebung (IDE), ist eine Plattform, in derverschiedene Programmierwerkzeuge, z.B. die Java-Entwicklungswerkzeuge (JDT), trans-parent vereint werden. Die Eclipse-Plattform setzt sich dabei aus modularen Softwarebau-steinen zusammen. Jeder Softwarebaustein stellt dafür eine Sammlung von Bibliothekenbereit, durch die die Funktionen und Fähigkeiten der IDE erweitert werden. Die Erweiter-barkeit der Plattform ist zentrales Architekturmerkmal für Eclipse und wurde von Be-ginn an durch ein Plugin-Konzept umgesetzt. Seit Version 3 stellt das OSGi-Framework,Equinox, die Basis für die Umsetzung von Plugins für Eclipse, womit diese dem OSGi-Komponentenmodell unterliegen. Seit dem entwickelt sich Eclipse zu einer Rich-Client-Plattform (RCP), die nicht nur Programmierwerkzeuge integriert, sondern aus deren Be-standteile beliebige Client-Anwendungen realisiert werden können. [8]

Plugins Wie bereits angedeutet sind Plugins Softwarebausteine, die die Eclipse-Platt-form um bestimmte Funktionen und Fähigkeiten erweitern. In Plugins können Pakete (unddamit Klassen und Schnittstellen) und Ressourcen exportiert, Komponenten bereitgestelltoder auch ganze Anwendungen realisiert werden. Eclipse ist selber aus einer Ansammlungvon Plugins realisiert. Beim Start der Plattform wird lediglich der Anwendungskern zurBereitstellung der Plugin-Mechanismen gestartet. Erst durch die erste Anforderung eines

31

3 Lösungsansatz

Abbildung 3.7: Erweiterungsbeziehungen zwischen Plugins [34]

Plugins wird dieses, zusammen mit den zur Ausführung benötigten Plugins, gestartet.Ein Plugin enthält in der Regel, neben seinem Programmcode, alle benötigten Ressourcensowie Metadateien, die das Plugin gegenüber dem System beschreiben. Wird ein neuesPlugin installiert, sind keine weiteren Angaben zur Ausführung dieses Plugins notwendig.Die Metadatei enthält die notwendigen Informationen, so z.B. den Namen des Plugins,deren Version und die Namen der Plugins, vom denen dieses abhängig ist. Durch dieexplizite Bekanntgabe von Abhängigkeiten kann das System einen Abhängigkeitsgraphenerzeugen und so alle notwendigen Plugins, in der vorbestimmten Reihenfolge, bereitstellen.[15]

Abhängigkeiten Es können zwei Formen von Abhängigkeiten zwischen Plugins unter-scheiden werden, zum einen die einfache Abhängigkeitsbeziehung und zum anderen dieErweiterungsbeziehung. Ein Plugin geht eine einfache Abhängigkeitsbeziehung ein, wenndieses Pakete oder Ressourcen aus einem anderen Plugin importiert (vorausgesetzt die-se wurden durch das andere Plugin exportiert). Das importierende Plugin nimmt dabeidie Rolle des abhängigen (engl. dependent), das exportierende die des vorausgesetzten(engl. prerequisite), Plugins ein. [15] Die Kennzeichnung der Rollen bzw. der Abhängig-keiten wird innerhalb der Metadateien explizit ausgewiesen. Hierfür gibt das vorausge-setzte Plugin, seine zu exportierenden Pakete bekannt. Das abhängige Plugin referenziertdas vorausgesetzte Plugin entweder direkt über seinen Namen oder indirekt über die zuimportierenden Pakete. Die zweite Form der Abhängigkeit, Erweiterungsbeziehung, wirdzwischen Plugins über Erweiterungspunkte (engl. Extension-Point) und Erweiterungen(engl. Extension) eingegangen. Die Abbildung 3.7 zeigt die Struktur von Erweiterungsbe-

32

3 Lösungsansatz

ziehungen zwischen Plugins mit Erweiterungspunkten und Erweiterungen. Dazu de�niertein Plugin einen Erweiterungspunkt über eine benötigte Schnittstelle (oder abstraktenKlasse) und verö�entlicht diese in seiner plugin.xml zusammen mit einem Schema zurBeschreibung der Struktur des Erweiterungspunktes. Im Schema wird der Aufbau einerErweiterung beschrieben und damit die bereitzustellenden Informationen bzw. Parameterfestgelegt. Das Plugin, das eine Erweiterung für einen Erweiterungspunkt zur Verfügungstellt, de�niert die geforderte Struktur des Schemas in seiner plugin.xml und macht da-mit die angebotene Realisierung bekannt. Die Auswertung der plugin.xml Datei erfolgtdurch das System zur Übersetzungszeit, da sich diese zur Laufzeit nicht verändert. Beider Verwendung von Erweiterungspunkten ist hingegen zu beachten, dass das Systemzur Laufzeit verändert werden kann � zu jedem Zeitpunkt können Plugins hinzugefügtbzw. entfernt werden � womit auch Erweiterungen hinzugefügt bzw. entfernt werden.Die Eclipse-Laufzeitumgebung benachrichtigt registrierte Beobachter über Veränderungender Plugin-Registrierungen. Zur Behandlung der Dynamik stellt die LaufzeitumgebungSchnittstellen und Hilfsklassen über das Paket org.eclipse.core.runtime.dynamichelperszur Verfügung, so z.B. IExtensionChangeHandler und ExtensionTracker. Oftmals wirddieser Sachverhalt bei der Behandlung von Erweiterungspunkten auÿer Acht gelassen, waseinen Neustart der IDE nach Installation bzw. Deinstallation von Plugins erforderlichmacht.

Bündel Mit Einführung des OSGi-Komponentenmodells [18], in Eclipse, werden Plug-ins durch OSGi-Bündel (engl. bundle) repräsentiert. Es besteht dennoch ein Unterschied,denn Plugins erweitern OSGi-Bündel, um die Möglichkeit der De�nition von Erweite-rungsbeziehung (durch Erweiterungspunkte und Erweiterungen). Weswegen OSGi-Bündeldas OSGi-Framework voraussetzten und Eclipse-Plugins die darauf aufsetzende Eclipse-Laufzeitumgebung. Grundsätzlich ist die Aufgaben eines OSGi-Bündels die Modularisie-rung einer Java-Anwendung. Hierzu zählen die Paketierung, die Verteilung sowie die Vali-dierung von Anwendungen und Komponenten. [13] Zur Realisierung der Modularisierungund damit der Trennung verschiedener Programmaspekte liefert das OSGi-Framework zujedem Bündel eine eigene Classloader-Instanz [15].

Classloader Der Classloader ist Bestandteil der virtuellen Java-Maschine (JVM) unddafür verantwortlich, dass Klassen in die virtuelle Maschine geladen werden. Beim Startder JVM, besitzt diese bereits einen System- bzw. Boot-Classloader, der dazu genutztwird Klassen aus dem Classpath in die virtuelle Maschine zu laden. Durch Ableitungvon der abstrakten Klasse java.lang.ClassLoader kann die virtuelle Java-Maschine, umeinen eigenen ClassLoader, erweitert werden. Der Classloader-Mechanismus des OSGi-Frameworks erweitert die virtuelle Java-Maschine um einen Bündel-Classloader. Die vor-handenen Classloader-Instanzen, des Boot-Classloader und der Bündel-Classloader, ste-hen über ein Delegationsnetzwerk miteinander in Verbindung. Kann ein Classloader eineAnforderung zum laden einer Klasse nicht erfüllen, leitet er diese an seinen benachbarten

33

3 Lösungsansatz

Classloader weiter. Die Struktur des Delegationsnetzwerks hängt direkt von den deklarier-ten Bündel-Abhängigkeiten ab. Alle Anfragen die nicht durch einen Bündel-Classloadererfüllt werden können, werden abschlieÿend an den Boot-Classloader delegiert. Die Mengealler Klassen die über den Classloader eines Bündels bereitgestellt werden können, gehörenzu seinem Class-Space. Der Class-Space eines Bündels beinhaltet demnach die Klassen:

• aus dem System-Classpath (Boot-Classloader),

• aus den importierten Paketen (indirekte Abhängigkeiten),

• aus den exportierten Paketen vorausgesetzter Bündel (direkte Abhängigkeiten)

[15]. Durch den vorgestellten Classloader-Mechanismus ermöglicht das OSGi-Framework,dass verschiedene Bündel in derselben JVM laufen und trotzdem das Prinzip der Kapse-lung zwischen Bündeln nicht verletzt wird. Dies bedeutet, dass in derselben JVM ausge-führte Bündel alle Klassen bzw. Pakete vor anderen Bündeln verstecken, auÿer jene, dieexplizit exportiert werden. Sämtliche Klassen eines Class-Space müssen einen eindeutigenNamen haben. Namen von Klassen in verschiedenen Bündeln dürfen jedoch identisch sein,da diese nicht vom selben Classloader geladen werden. Durch diese Architektur unterstütztOSGi ein Modell, in dem mehrere Versionen der gleichen Klasse in eine JVM-Instanz ge-laden werden können. Dadurch können die Abhängigkeiten verschiedener Bündel optimalerfüllt werden, denn unterschiedliche Bündel können verschiedene Versionen der gleichenKlasse benötigen [13].

Dienste Im OSGi-Modell können Bündel Dienste deklarieren. Ein Dienst, im Sinne die-ses Modells, wird semantisch durch seine Schnittstelle (engl. service interface) deklariertund durch ein Dienstobjekt (engl. service object) implementiert. Die Schnittstelle desDienstes stellt die Spezi�kation seiner Methoden dar. Ein Dienstobjekt gehört zu einemBündel und wird in dessen Kontext verwaltet. Dienste ermöglichen eine lose Koppelungder einzelnen Anwendungsbestandteile und erlauben dadurch die �exible Wiederverwen-dung dieser, repräsentiert durch Bündel. Durch diese Architektur erlaubt das Modelldie Trennung von Spezi�kation und Implementierung. Dazu exportiert ein Bündel eineDienstschnittstelle während ein anderes die Implementierung dazu liefert. Insbesonderekönnen auch mehrere Implementierungen des gleichen Dienstes verfügbar sein, d.h. meh-rere Bündel stellen eine Implementierung einer Dienstschnittstelle bereit. Ebenso kannein Dienstobjekt mehrere Dienstschnittstellen bedienen. Damit Dienste lokalisiert werdenkönnen, stellt das OSGi-Framework ein zentrales Dienstverzeichnis (engl. service registry)zur Verfügung, über das Dienste nachgeschlagen bzw. angefordert werden können. DieAbbildung 3.8 zeigt das Dienstverzeichnis des OSGi-Frameworks zur Darstellung der be-schriebenen Zusammenhänge. Das Dienstverzeichnis steht somit als Vermittler von Diens-ten zwischen Bündel. Die Ausführung eines lokalisierten Dienstes erfolgt hingegen ohneVermittlung, d.h. als direkter Funktionsaufruf � da sich Klassen von Bündel in der glei-chen JVM be�nden. Existieren mehrere Implementierungen eines Dienstes müssen sichdiese ggf. unterscheiden lassen, dazu kann ein Dienstanbieter bei der Registrierung ne-ben der Dienstschnittstelle zusätzliche Eigenschaften zu seinem Dienst de�nieren, die vom

34

3 Lösungsansatz

Abbildung 3.8: Dienstverzeichnis des OSGi-Framework [29]

Dienstnutzer zum Nachschlagen verwendet werden können. Abhängigkeiten zwischen demBündel, zu dem ein Dienst gehört, und den Bündeln, die diesen Dienst nutzen, werdenvom Framework verwaltet. So werden registrierte Dienstnutzer über die Deregistrierungeines Dienstes ggf. benachrichtigt. [13] Vergleicht man die Mechanismen zur Entkopp-lung für Bündel mit denen für Plugins (also Dienste und Erweiterungsbeziehungen) sindAnalogien festzustellen. Beispielsweise entspricht die Plugin-Registrierung dem zentralenDienstverzeichnis. Auch die Rollen Nutzer und Anbieter können auf Erweiterungspunkteund Erweiterungen übertragen werden � so übernimmt ein Erweiterungspunkt die Rolleeines Nutzers und die Erweiterungen die der Anbieter. Die Ansätze unterscheiden sichhingegen in der Multiplizität der Beziehung zwischen Nutzer und Anbieter � während 1Erweiterungspunkt N Erweiterungen aufnimmt, ermöglicht das OSGi-Modell N Dienst-nutzer mit M Dienstanbietern zu verknüpfen. Für Bündel in denen Dienste konsumiertwerden, gilt es die Dynamik des Systems zu beachten. Wie bereits für Erweiterungspunktein Plugins stehen für das Konsumieren von Diensten Schnittstellen und Hilfsklassen zurBehandlung der Dynamik bereit. Das OSGi-Framework stellt zu diesem Zweck beispiels-weise, über das Paket org.osgi.util.tracker, einen ServiceTracker zur Verfügung.

Komponenten Betrachtet man das OSGi-Modell nach den Kriterien Semantik, Syn-tax und Komposition, erfüllen Bündel alle Kriterien für Komponenten (und damit auchEclipse-Plugins). Die bereitgestellten Mechanismen zur Kollaboration, durch Dienste bzw.Erweiterungsbeziehungen, lassen das Bild einer zusammengesetzten Komponente erah-nen. Wobei die Struktur, Aufgrund der losen Kopplung, keine starre Zusammensetzungvon Komponenten zu neuen Komponenten ermöglicht. Insbesondere werden Bündel nichtso zusammengesetzt, dass zwei oder mehr Bündel zu einem neuen Bündel verschmel-zen. Die De�nition von Diensten ermöglichen die Trennung von Spezi�kation und Im-plementierung. Bündel sind dadurch nur von den Spezi�kationen der Dienste abhängig,die Implementierungen können (auch im laufenden Betrieb) nach Bedarf ausgetauschtwerden. [13] Die lose Kopplung hat aber nicht nur Vorteile, denn der vorgestellte im-

35

3 Lösungsansatz

Abbildung 3.9: Dienstkomponenten-Laufzeitumgebung [17]

perative Ansatz, erhöht die Komplexität bei der Umsetzung von Bündel bzw. Pluginsund ggf. deren Startzeit bzw. Speicherverbrauch. Wenn beispielsweise ein Dienst zur Aus-führung andere zwingend benötigt, dann müssen die erforderlichen Dienste beobachtetund der abhängige, je nach deren Verfügbarkeit, registriert bzw. deregistriert werden.Des Weiteren werden beim imperativen Ansatz alle Dienste gleich beim Starten einesBündels erzeugt und registriert, ganz unabhängig davon ob diese überhaupt jemals be-nötigt werden. Gerade bei Systemen, die aus zahlreichen Bündeln bestehen, kann diesleicht zur Erhöhung von Startzeit und Speicherverbrauch führen. Diese Probleme wer-den im OSGI-Komponentenmodell durch Einsatz eines deklarativen Dienstansatzes adres-siert. In diesem werden Dienste durch Dienstkomponenten bereitgestellt und referenziert.Dienstkomponenten (engl. service component) bestehen aus einer XML-Beschreibung,der Komponentenbeschreibung (engl. component description), und einer Komponenten-instanz (engl. component instance). Die Komponentenbeschreibung beinhaltet alle not-wendigen Informationen über eine Dienstkomponente, wie beispielsweise den Klassen-namen (zur Instantiierung der Komponente) oder die bereitgestellten bzw. benötigtenDienstschnittstellen. Zum Zweck der Bekanntgabe wird die Komponentenbeschreibungin der Metadatei des Bündels bzw. Plugins eingetragen. Mit diesen Informationen in-stantiiert die Dienstkomponenten-Laufzeitumgebung (engl. service component runtime)Komponenten, wenn diese das erstmal angefordert werden und alle zwingend benötigtenAbhängigkeiten verfügbar sind. Die Abbildung zeigt die Struktur der Dienstkomponenten-Laufzeitumgebung zur Darstellung der beschriebenen Zusammenhänge. Insbesondere ent-fällt die Notwendigkeit der Registrierung von Komponenten (und damit ggf. der Bündel-Aktivator), da Bündel durch die Laufzeitumgebung überwacht und so gefundene Dienst-

36

3 Lösungsansatz

komponenten automatisch verfügbar gemacht werden. Explizit deklarierte Abhängigkei-ten, auf Dienstschnittstellen, werden durch die Laufzeitumgebung ausgelöst und denKomponenten bereitgestellt. Des Weiteren übernimmt die Laufzeitumgebung das Life-Cycle-Management der Komponenten und deaktivierte diese, wenn Abhängigkeiten nichtmehr erfüllt werden können, weil Bündel bzw. Komponenten aus dem System entferntwurden. Im deklarativen Ansatz kommen Komponenten ohne Abhängigkeiten auf dasOSGi-Framework aus und werden daher durch einfache Java-Objekte (POJO) repräsen-tiert. Ein weiterer Vorteil, der sich dadurch ergibt, ist, dass Dienstkomponenten ohne dieLaufzeitumgebung auf einfache Weise getestet werden können. [17] Es existieren weitereFrameworks die einen ähnlichen Ansatz verfolgen und auf dem OSGi-Komponentenmodellaufsetzen, zu den Vertreter gehören beispielsweise Spring Dynamic Modules, Apache FlexiPOJO oder Guice Peaberry.

Launching-Framework Zum Starten und Debuggen von Anwendungen bietet EclipseLauncher, die durch das Eclipse-Launching-Framework ausgeführt werden. Wie alles inEclipse werden Launcher durch Plugins bereitgestellt und sind daher nicht fester Bestand-teil des Eclipse-Frameworks. Für jeden Anwendungstyp (Launch-Con�guration-Type)kann für Eclipse ein eigener Launcher bereitgestellt werden. Im Eclipse-Softwareentwick-lungskit (SDK) sind bereits diverse Launcher verfügbar, die beispielsweise das Debug-gen und Starten von Java-Anwendungen, -Applets, JUnit-Testfällen oder Eclipse-Anwen-dungen ermöglichen. Die echte Stärke des Launching-Framework liegt jedoch in seinerErweiterbarkeit durch eigene Launcher. Hierfür sind neben dem Launcher (Launch-Dele-gate), die Launch-Kon�guration und entsprechende Ober�ächen (Launch-Con�guration-Tabs) bereitzustellen. In den Launch-Kon�gurationen wird die Persistierung der Kon�gu-rationen vorgenommen. Der Launcher ist für alle vorbereitenden Maÿnahmen und demanwendungsspezi�schen Start zuständig. [27]

Builder Wie jede moderne IDE bietet auch Eclipse dem Anwender die Möglichkeit Quell-code in ausführbaren Code zu übersetzen. Analog zu den Launchern ist auch diese Funk-tionalität nicht fester Bestandteil des Eclipse-Frameworks, sondern wird über Plugins (derJDT) bereitgestellt. Das Eclipse-Framework steuert über ein abstraktes Modell die demBuild-System bereitgestellten Komponenten � Builder. Der Prozess der Übersetzung wirdals Build-Vorgang bezeichnet und ist nicht nur auf Quellcode beschränkt. Zu jeglicheQuell-Ressourcen, wie z.B. Kon�gurationsdateien, lassen sich Builder bereitstellen, diezu diesen abgeleitete Ressourcen erzeugen. Damit repräsentieren abgeleitete RessourcenAusgabedateien, die sich erneut aus den Quellen reproduzieren (ableiten) lassen. [22]

Java Development Tools (JDT) Die JDT stellen die Entwicklungsumgebung für Java-Anwendungen in Eclipse. Sie sind Kernbestandteil des Eclipse-Softwareentwicklungskits.Mit Editoren, Assistenten, Vorlagen, Buildern und Refaktorisierungswerkzeugen stellendie JDT Funktionen zur Verfügung, die Entwickler bei der Erstellung von Java-Anwen-dungen unterstützen. Auch Launcher zum Debuggen und Starten von Java-Anwendungen,

37

3 Lösungsansatz

-Applets oder enthaltenen JUnit-Testfällen werden durch die JDT bereitgestellt. Kern derJDT sind die Bestandteile, des Java-Modells, des abstrakten Syntaxbaums (AST) und derJava-Suchmaschine (engl. search engine). Diese stehen allen Erweiterungen zur Verfügungund erlauben das Navigieren, die Analyse und das Modi�zieren von Java-Programmen.[22]

Plugin Development Environment (PDE) Eclipse-PDE, als Teil des Eclipse-Software-entwicklungskit, bietet Werkzeugunterstützung zum Schreiben, Testen und Debuggen vonEclipse-Plugins und erweitert damit die Fähigkeiten der JDT. Dafür stellt das PDE eineReihe von Assistenten und Vorlagen zur Verfügung, die die Erstellung von Plugins ver-einfachen. Es gibt sowohl spezielle Editoren für Plugin- und Metadaten. Auÿerdem bietetdas PDE einen Browser für die Erweiterungsregistratur und zur Darstellung von Ab-hängigkeiten zwischen Plugins. Es gibt Spezialfunktionen, die Zyklen in Abhängigkeitenau�nden oder nicht verwendete Abhängigkeiten aufspüren. Auch bei der De�nition vondeklarativen Dienstkomponenten unterstützt das PDE mit entsprechenden Assistentenund Editoren. Eclipse ist eine komplizierte Plattform. Mit dem PDE ist es allerdings ge-lungen die zum Teil schwierigen Kon�gurationsarbeiten hinter gra�schen Ober�ächen zuverbergen [15]. Die Stärken des PDE zeigen sich insbesondere beim Testen und Debuggenvon Plugins. Dort übernimmt das PDE alle notwendigen Schritte, von der Kon�gurationbis hin zur Bereitstellung einer autonomen Arbeitsumgebung (Testumgebung), für diezu testenden Plugins (und allen zur Ausführung notwendigen). Durch das PDE werdenLauncher für das Starten und Debuggen von Eclipse-Anwendungen und den darin enthal-tenen JUnit-Testfällen bereitgestellt. Zur Isolation von zu testenden Plugins wird durchdas PDE eine Testumgebung, in einer neuen Eclipse-Instanz, gestartet. Womit gewähr-leistet ist, dass die produktive Umgebung, von Fehlern und Ausnahmen in zu testendenPlugins, unbeein�usst bleibt (da jede Instanz in einer separaten JVM läuft).

Team Die Team-Komponente dient als Basis für die Entwicklung von Versions- undKon�gurationsmanagement-Systemen (VCM) in Eclipse und erlaubt dadurch die gleich-zeitige Nutzung von Ressourcen innerhalb einer Entwicklergruppe. Dazu wird ein Projektmit einem Repository verknüpft, das die Verwaltung übernimmt. Über das Repositorysteht das Projekt, und Informationen (z.B. die Historie) über das Projekt, den Team-Mitgliedern zur Verfügung. Im Eclipse-SDK ist eine konkrete Implementierung für CVSenthalten. Für den Nachfolger, von CVS, SVN stehen die Plugins Subversive oder Subclip-se bereit. Des Weiteren bieten verschiedene Hersteller, wie z.B. Rational, Serena, Starbaseoder Merant, Integrationen (eigene Plugins) für ihre Produkte an [35].

JQuery JQuery ist ein Werkzeug zur abfragebasierten Suche im Quellcode � ein abfrage-basierter (engl. query-based) Java-Quellcode-Browser. Es ist als Eclipse-Plugin realisiertund arbeitet auf Basis der logischen Abfragesprache TyRuBa, die eine Prolog-ähnlicheSyntax besitzt. Aus dem AST der ausgewählten Java-Projekte werden durch JQuerydie notwendigen Fakten für die TyRuBa-Datenbank generiert. Im Anschluss kann der

38

3 Lösungsansatz

Quellcode nach Kriterien einer Abfrage untersucht werden. Die Ergebnisse einer Abfragewerden automatisch an den Quellcode gebunden, der durch das Java-Modell der JDT re-präsentiert wird. Dadurch ist eine Navigation zwischen Abfragen-Ergebnis und Quellcodemöglich. Mit diesen Mitteln können Benutzer Ansichten de�nieren und die gewünschtenAspekt ihrer Programme visualisieren. [3]

SWT und JFace Im Umfang der Standard Java-Bibliothek sind Klassen und Schnitt-stellen, auf Basis der Bibliotheken Swing und Abstract Window Toolkit (AWT), zur Rea-lisierung von gra�schen Benutzerober�ächen enthalten. Eclipse-Anwendungen nutzen je-doch die Bibliothek des Standard Widget Toolkits (SWT) zur Realisierung von Benutzer-ober�ächen. Anders als die Bibliotheken, die im Standard-Umfang enthalten sind, imple-mentiert SWT seinen Funktionen ausschlieÿlich auf Basis des Betriebssystems. Hierdurchbetten sich SWT-Anwendungen vollständig in die zugrunde liegende Desktopumgebungein und haben nicht das für Java-Programme typische Aussehen und zum Teil schwer-fällige Fensterverhalten. Anderseits geht damit ein Teil der Flexibilität verloren, da dasSWT abhängig von dem Umfang der unterstützen Funktionen des Betriebssystems ist.Zudem müssen Programmierer die Freigabe von System-Ressourcen (wie z.B. Farben oderSchriftarten) explizit anweisen, da diese Ressourcen von der automatischen Speicherbe-reinigung (GC) nicht freigegeben werden (insbesondere weil sie zwischen Steuerelementenwiederverwendet werden und der GC nicht über die notwendigen Informationen verfügt).Aufbauend auf dem SWT stellt JFace seine Steuerelemente (z.B. Bäume, Listen, Wizardsoder Dialoge) bereit, die Entwickler bei der Umsetzung von gra�schen Ober�ächen un-terstützen. Das Plugin der Eclipse Benutzerschnittstelle (UI) realisiert auf Basis dieserBibliotheken bzw. Plugins, SWT und JFace, Benutzerober�ächen und Standarddialoge,die zusammen die Workbench für eine Eclipse-Anwendung realisieren. [15]

39

4 Implementierung

4.1 Organisation

4.1.1 Plugins

Der Refactoring Tool Testers unterteilt seine Programmaspekte in verschiedene Plugins,die die notwendigen Komponenten bereitstellen. Zu diesen Komponenten (bzw. Plugins)gehören:

de.fernunihagen.rtt ist das RTT-Core-Plugin und beinhaltet alle von der Benutzer-schnittstelle unabhängigen Programmaspekte. Dazu gehören Annotationen für de-klarative Testadapter, Schnittstellen zur De�nition von Dienstkomponenten (wiez.B. Testadapter, Orakel, Repositories und Test-Runner), das Modell und der An-wendungskern, der die Koordinationslogik beinhaltet. Des Weiteren stellt das Core-Plugin konkrete Implementierungen für das syntaktische, semantische Java-Orakelund den dazugehörigen Test-Runnern zur Verfügung.

de.fernunihagen.rtt.thirdparty kapselt eine Sammlung von Java-Bibliotheken (in Jar--Archiven), auf die RTT-Plugins Abhängigkeiten haben, die aber nicht Teil der RTT-eigenen Implementierung sind. Dazu gehören beispielsweise Contract4J oder Log4J.

de.fernunihagen.rtt.framework.repository.team.svn stellt einen Konnektor zur Anbin-dung von SVN Repositories, durch Subversive, zur Verfügung.

de.fernunihagen.rtt.ui ist das RTT-UI-Plugin und enthält alle Komponenten der Be-nutzerschnittstelle. Dazu gehören eine Ansicht zur Darstellung und Analyse vonTestergebnissen und ein Kon�gurationsassistent. Des Weiteren stellt das PluginSchnittstellen zur De�nition von Dienstkomponenten zur Verfügung, die der Er-weiterung der Ansicht bzw. Analyse-Fähigkeiten dienen. Zudem erweitert das Plug-in das Launching-Framework um einen Launcher zum Start und Debuggen vonTests. Neben diesen Bestandteilen stellt das UI-Plugin konkrete Implementierungenfür einen deklarativen Java-Testadapter (ohne Abfragewerkzeug) und verschiedeneAnalyse-Werkzeuge zur Verfügung.

de.fernunihagen.rtt.ui.app beinhaltet den Prüfstand (engl. test bench), der vom Laun-cher verwendet wird, um Tests isoliert auszuführen. Die Mittel zur Darstellung undAnalyse von Testergebnissen, die durch das RTT-UI-Plugin bereitgestellt werden,sind in der Testbench verfügbar.

40

4 Implementierung

Abbildung 4.1: Schichten des Refactoring Tool Testers

de.fernunihagen.rtt.ui.testadapter.jquery enthält einen deklarativen Abfragewerkzeug-Testadapter, der JQuery verwendet (JQuery-Testadapter).

4.1.2 Abhängigkeiten

Die Umsetzung des Testwerkzeugs ist in den, in Abbildung 4.1, gezeigten Schichten unter-teilt. Die Plugins, aus dem Unterkapitel 4.1.1, sind diesen Schichten zugeordnet. Des Wei-teren zeigt die Abbildung 4.1 die internen Abhängigkeiten, zwischen den Plugins, des Test-werkzeugs. Dabei ist die Richtung der Abhängigkeiten durch die dargestellten Pfeile ausge-wiesen. Die Plugins der Benutzerschnittstelle, de.fernunihagen.rtt.ui.testadapter.jquery,de.fernunihagen.rtt.ui und de.fernunihagen.rtt.ui.app, sind der Präsentationsschichtzugeordnet. Die RTT SVN-Anbindung, de.fernunihagen.rtt.framework.repository.team.svn, stellt die Brücke zur Datenhaltung � von Probanden in Repositories. Die An-wendungslogik wird durch das Plugin de.fernunihagen.rtt bereitgestellt. Dasde.fernunihagen.rtt.thirdparty Plugin beinhaltet alle verwendeten, nicht in Eclipse ent-haltenen, Drittanbieter-Bibliotheken. Die Zuordnung des deklarativen JQuery-Testadap-ters zur Präsentationsschicht ist Aufgrund der fehlenden Trennung, zwischen Benutzer-schnittstelle und Anwendungslogik, vieler Refaktorisierungswerkzeuge erfolgt. Diese be-nötigen zur Ausführungen einen UI-Thread, um die Konsistenz ihrer Datenstrukturen zugewährleisten. Für Testfälle auf Basis dieses Testadapters entfallen die Abhängigkeiten aufdie Benutzerschnittstelle des RTT, da der Testfall durch das Framework ausgeführt wird,das diese verbirgt. Damit beschränken sich die Abhängigkeiten, die zur Deklaration vonTestfällen für Refaktorisierungswerkzeuge notwendig sind, auf das RTT-Core Plugin.

41

4 Implementierung

4.1.3 Pakete

Die Organisation von Klassen, Schnittstellen und Annotationen, des Refactoring ToolTesters, unterteilt sich in Pakete. Diese werden durch die im Unterkapitel 4.1.1 beschrie-benen Plugins exportiert. Konkrete Implementierungen sind in internen (engl. internal)Paketen organisiert, die damit fragile Programmierschnittstellen kennzeichnen � d.h. diedort enthaltenen Programmelemente können jeglicher Art von Änderung, zwischen zweiPlugin-Versionen, unterliegen. Im Gegensatz dazu enthalten die verbleibenden Pakete ex-terne Programmierschnittstellen, die zur Sicherung der Kompatibilität, zwischen Nutzerund Anbieter einer Programmierschnittstelle, keinen Änderungen unterliegen. Verwen-dete Technologien bzw. Abhängigkeiten auf andere Werkzeuge sind in den Paketnamenimplizit ausgewiesen, so z.B. JDT oder SVN � Klassen auÿerhalb dieser Pakete habenkeine Abhängigkeiten auf diese Werkzeuge. Damit gewährleistet das Testwerkzeug, dassAbhängigkeiten auf andere Werkzeuge in zentralen Paketen organisiert sind und erreichtdamit seine Erweiterbarkeit, um beispielsweise Testadapter für Refaktorisierungswerkzeu-ge anderer Programmiersprachen. Eine tabellarische Übersicht über die realisierte Paket-struktur ist dem Anhang, in den Tabellen A.2, A.4 und A.6, beigefügt.

4.2 Framework

4.2.1 Struktur

Wie bereits angedeutet ist der Refactoring Tool Tester als Framework, für das auto-matisierte Testen von Refaktorisierungswerkzeugen, entworfen. Das Testwerkzeug ist da-mit um neue Testadapter, Orakel, Test-Runner, Repositories und Analyse-Werkzeuge er-weiterbar. Die zentralen Konzepte zur Erweiterung des Testwerkzeuges stellt das OSGi-Komponentenmodell mit Bündeln und Dienstkomponenten. Auch wenn Eclipse seit Ver-sion 3 auf OSGi basiert, nutzen nur wenige Plugins die neuen Möglichkeiten des OSGi-Frameworks aus. Von daher sind Plugins, die Dienste bzw. Dienstkomponenten de�nie-ren, eher selten aufzu�nden. Erweiterungsbeziehungen zwischen Plugins sind immer nochder zentrale Mechanismus um Eclipse zu erweitern, so dass das Testwerkzeug auf Er-weiterungen zurückgreifen muss, um an bestehende Funktionalitäten anzuknüpfen. Je-doch werden Erweiterungspunkte vom Testwerkzeug nicht bereitgestellt � hier kommenDienstkomponenten zum Einsatz. Die Probleme, die sich dadurch ergeben, dass man sichnicht nur in der Welt der Dienstkomponenten bewegt, sind, dass Dienste auÿerhalb derDienstkomponenten-Deklarationen verfügbar gemacht werden müssen. Aus diesem Grundsetzt das Framework, des Testwerkzeuges, neben dem deklarativen Dienstansatz, auch denimperativen ein. Hierzu stellt das Framework Fassaden (RTTCore und RTTCoreUI) zumZugri� auf Dienste auÿerhalb der Dienstkomponenten-Deklaration bereit. Die Abbildung4.2 zeigt eine Übersicht über die interne Struktur des RTT-Core-Plugins und weist ver-wendete Schnittstellen und Komponenten aus. Zur Realisierung der Fassade RTTCore

42

4 Implementierung

Abbildung 4.2: Übersicht der RTT-Core Komponentenstruktur

kommen Anbieter als Dienstkomponenten zum Einsatz, die die Verwaltung und den Zu-gri� auf die RTT Dienste von Orakeln, Testadaptern, Repositories und Beobachtern er-möglichen. Die gezeigten Anbieter und Test-Runner werden durch das RTT-Core-Pluginmit Hilfe von ServiceTrackern referenziert. Über die Schnittstelle der Fassade können die-se kon�guriert werden. Vor dem Start eines Testlaufs bestimmt der Anwendungskern,über die Fassade, die aktiven Anbieter (engl. provider) und Test-Runner. Die enthaltenenOrakel, Java-Übersetzer und JUnit, sind als Dienstkomponenten über die gleichnamigenSchnittstellen realisiert. Die Registrierung wird vor dem Start des Plugins, wie für alleDienstkomponenten, durch die OSGi-Laufzeitumgebung übernommen.

Die Abbildung 4.3 vervollständigt das Bild der RTT-Komponentenstruktur, aus Abbil-dung 4.2, um die verbleibenden Plugins. Analog zur RTT-Core-Fassade stellt die RTT-Core-UI-Fassade die aktiven Dienstanbieter der Benutzerschnittstelle bereit. Zu diesenDienstanbietern gehört der Anbieter für Aktionen der Benutzerschnittstelle, der die Ver-waltung und Bereitstellung von Kontext-Menü-Einträgen für die Testergebnisansicht über-nimmt. Weitere Dienstkomponenten des RTT-UI-Plugins sind der Inhaltsanbieter fürTestergebnisse, der deklarative Java-Testadapter und konkrete Implementierungen fürAktionen1 der Testergebnisansicht (z.B. Wiederholung einer Refaktorisierung). Die Test-ergebnisansicht ist als Erweiterung, des Erweiterungspunktes org.eclipse.ui.views, rea-lisiert. Des Weiteren erweitert das RTT-UI-Plugin das Launching-Framework um einen

1Diese sind aus Gründen der Übersichtlichkeit nicht im Komponentendiagramm aufgeführt.

43

4 Implementierung

Abbildung 4.3: Übersicht der RTT Komponentenstruktur

Launcher zum Starten und Debuggen von Tests. Zu den Bestandteilen der Erweiterun-gen gehören die Launch-Kon�gurations-Registergruppe (engl. launch con�guration tabgroup) und der Launch-Delegate. Während die konkreten Implementierungen der Launch-Kon�gurations-Registergruppe und der dazugehörigen Registerkarten im RTT-UI-Pluginenthalten sind, ist die Implementierung des Launch-Delegates Teil des Testbench-Plugins(de.fernunihagen.rtt.ui.app).

Das Testbench-Plugin beinhaltet eine Erweiterung zum Erweiterungspunkt Applikati-on (org.eclipse.core.runtime.applications), der den Startpunkt einer Eclipse-Anwendungauszeichnet. Über diese Erweiterung startet der Launcher die Testbench in einer neuenEclipse-Instanz. Im Anschluss bestimmt die Testbench über den gleichen Erweiterungs-punkt die zu startende Workbench-Anwendung, um dem Tester eine gra�sche Ober�ächebereitzustellen. Vor dem Start der Workbench-Anwendung registriert sich die Testbenchals Test-Harnisch (engl. test harness) bei der Eclipse-Plattform, um mit dem Start derWorkbench zurückgerufen zu werden. In der Rückruf-Funktion (engl. callback-function)erfolgt der Start des Anwendungskerns. Alle notwendigen Parameter sind in der Testkon�-guration enthalten, die vom Launcher als temporäre XML-Datei vor dem Start hinterlegtwird. Als Übergabeparameter wird durch die Ausführungskette � Testbench-, Workbench-Anwendung und Anwendungskern � die URI der Testkon�guration delegiert.

Die verbleibenden Plugins, JQuery-Testadapter und Team-SVN-Konnektor, beinhaltendie Realisierungen der Schnittstellen Testadapter und Repository � als Dienstkompo-nenten.

44

4 Implementierung

Abbildung 4.4: Übersicht der RTT Modellelemente

4.2.2 Modell

Wie im Unterkapitel 3.2 beschrieben, ist der RTT nach dem MVC-Architekturmuster ent-worfen. Das Modell wird zur Entkopplung der Präsentationsschicht von der Anwendungs-logik verwendet. Hierzu benachrichtigt der Anwendungskern Beobachter (z.B. Analyse-werkzeuge) über Modelländerungen. Das Modell beinhaltet alle Kon�gurationsparameterund Testergebnisse, die zur Analyse notwendig sind. Da der Anwendungskern mit seinenAktoren hierarchisch aufgebaut ist, spiegelt das Modell diese Struktur wieder und ist des-wegen nach dem Composite-Entwurfsmuster realisiert. Damit stehen Modellelemente ineiner Teil-Ganzes-Hierarchie in Beziehung, die das Modell als Baumstruktur präsentiert.

Die Abbildung 4.4 gibt einen Überblick über die Klassen-Hierarchie der Modellelemente,als UML-Klassendiagramm. Die Klasse AbstractTestElement stellt die Basis-Klasse allerModellelemente in der Klassen-Hierarchie dar. Kindelemente haben die abstrakte KlasseTestElement als Basis-Klasse und repräsentieren damit, in der Teil-Ganzes-Hierarchie,atomare Test- bzw. Teilergebnisse (z.B. Ausnahmen, Übersetzungsprobleme oder Informa-tionen über eine Refaktorisierung). Zusammengesetzte Testergebnisse (z.B. Testkontextoder Testsitzung) werden durch Ableitung von der Basis-KlasseAbstractTestElementContainer realisiert. Die gezeigte Struktur erlaubt, dass Kompo-sitionen von Testergebnissen rekursiv aufgebaut werden. Klassi�ziert man die KlassenAbstractTestElementContainer und TestElement nach ihren Rollen, übernehmen die

45

4 Implementierung

Behälter (AbstractTestElementContainer) die Vater-Rollen und die enthaltenen Teil-bzw. Testergebnisse (TestElement) die der Kinder. Die Navigation zwischen diesen Mo-dellelementen ist sowohl in Richtung der Väter als auch der Kinder möglich, so dassvon jedem Punkt aus alle Modellelemente zugreifbar sind. Die Beziehungen zwischen denzusammengesetzten und atomaren Testergebnissen werden im Modell über Schnittstel-len, ITestElement und ITestElementContainer, abgebildet und ermöglichen damit denAustausch der Implementierung.

Des Weiteren führt das Modell die im Unterkapitel 3.3 beschriebenen Modellelemen-te und die dazugehörigen Schnittstellen, Testkontext (TestContext) und Testsitzung(TestRunSession), ein. Die Sitzung fasst das gesamte Modell, über die einzelnen Testkon-texte, zusammen und wird im Diagramm durch den Einstiegspunkt des Anwendungskerns,die ToolTestApplication, repräsentiert. Da Testsitzungen, in diesemModell, zusammenge-setzt sein können, ist eine Unterscheidung zwischen TestRunSession undTestRootRunSession notwendig. Die TestRootRunSession repräsentiert im Modell dendedizierten Einstiegspunkt, der alle Sitzungen zusammenfasst und für sich selber dieVater-Rolle übernimmt (rekursive Struktur). Neben dem Zugri� auf Testergebnisse er-möglicht die Testsitzung den Zugri� auf die Testkon�guration und die zu verwendendenProbanden-Projekte, die alle Kontexte einer Sitzung gemeinsam haben. Eine ähnlicheStruktur weisen die enthaltenen Testkontexte, TestContext und TestRootContext, auf.Wobei der TestRootContext sich nicht selber referenziert, sondern lediglich einen Start-punkt innerhalb einer Sitzung quali�ziert � d.h. die Vater-Rolle für einen TestRootContextwird immer durch eine Testsitzung übernommen. Jeder Testkontext ermöglicht, indi-rekt über die Sitzung, den Zugri� auf Probanden und die Testkon�guration. Des Wei-teren stellt ein Kontext den Bezug zu seinem Aktor her, so dass die enthaltenen Test-ergebnisse diesem zugeordnet werden können. Über die Schnittstelle IObservable, derTestRootRunSession, können Beobachter für Änderungen des gesamten Modells regis-triert werden. Die Registrierung von Dienstkomponenten als Modell-Beobachter wirddurch die ToolTestApplication vor dem Start eines Testlaufs übernommen.

Die Abbildung 4.5 zeigt die De�nition der, in Abbildung 4.4 gezeigten, Schnittstellen undderen Beziehungen. Die Basisschnittstelle ITestElement de�niert den Zugri� auf denVater-Behälter und die Testsitzung. Neben diesen Bestandteilen stehen Dienste zur Ab-frage von Status- (z.B. Verarbeitungsergebnis, Verarbeitungszustand oder Durchlaufzeit)und Anzeige-Informationen (z.B. Anzeigename) zur Verfügung. Das Verarbeitungsergeb-nis (Result) ermöglicht es einem übergeordneten Controller (z.B. Test-Runner), ohne dieStruktur der Modellelemente zu kennen, den Kontroll�uss zu steuern. Diese werden durcheine Aufzählung (engl. enumeration) repräsentiert und können miteinander verknüpft wer-den. Es werden die Verarbeitungsergebnisse aus Tabelle 4.1 unterschieden. In dieser De-�nition besitzt jede Konstante eine Kardinalität, die die Wertigkeit des Ergebnisses imZweierkomplement kennzeichnet. Durch Akkumulation werden zwei oder mehr Ergebnisseverknüpft, die resultierende Zahl kennzeichnet mit dem höchstwertigen Bit die Kardina-lität des zusammengesetzten Ergebnisses. Wird beispielsweise das VerarbeitungsergebnisOK mit einem ERROR verknüpft, ist das resultierende Verarbeitungsergebnis ERROR.

46

4 Implementierung

Abbildung 4.5: Schnittstellen des RTT Modells

Name Kardinalität BedeutungNONE 1 Besitzt kein VerarbeitungsergebnisIGNORED 2 Element wurde von der Verarbeitung ausgeschlossenOK 4 Erfolgreiche VerarbeitungFAILURE 8 Aufgedeckter FehlerERROR 16 Ausnahmefehler in der VerarbeitungUNDEFINED 32 Verarbeitungsergebnis ist nicht verfügbar

Tabelle 4.1: Verarbeitungsergebnisse im RTT Modell

Übertragen auf zusammengesetzte Testergebnisse führt der Fehlschlag eines Teilergebnis-ses zum Fehlschlag des Ganzen.

Die Tabelle 4.1 gibt einen Überblick über die verfügbaren Verarbeitungsergebnisse zu-sammen mit ihren Kardinalitäten und den zugeordneten Bedeutungen. Modellelementeohne Verarbeitungsergebnis kennzeichnen dies über den Status NONE. Modellelemen-te, denen ein Verarbeitungsergebnis zugeordnet werden kann, werden mit dem StatusUNDEFINED initialisiert, um die ausstehende Bearbeitung zu kennzeichnen. Nach Ab-schluss erfolgt der Wechsel in einen Erfolgs- (OK) oder Fehlerstatus (FAILURE oderERROR). Das Verarbeitungsergebnis FAILURE weist auf einen syntaktischen oder se-mantischen Fehler hin, ohne dass in der Verarbeitung Ausnahmen (engl. exceptions) auf-getreten sind. Im Vergleich dazu kennzeichnet der Status ERROR einen Fehler, der durchdas Auftreten einer Ausnahme ausgelöst wurde. Dabei können Ausnahmen durch Aktoren

47

4 Implementierung

Abbildung 4.6: Verarbeitungszustände eines Modellelements

oder von diesen ausgeführten Testfällen ausgelöst werden - d.h. auch in JUnit-Testfällen.Für den Fall das eine Ausnahme nach Refaktorisierung in einem JUnit-Testfall ausgelöstwird, deutet dies auf einen semantischen Fehler hin. Von der Verarbeitung ausgeschlosseneElemente werden durch IGNORED gekennzeichnet.

Neben den Verarbeitungsergebnissen unterscheiden die Aktoren Ausführungsstadien (engl.run stages), die Kennzeichnen in welchem Stadium sich die Verarbeitung be�ndet. Zu denAusführungsstadien gehören die Initialisierung (INIT ), Ausführung (RUN) und Bereini-gung (DISPOSE). Mit diesen Informationen kann ein Modellelement der Verarbeitungs-phase eines Aktors zugeordnet werden.

Zusammengesetzte Testergebnisse werden durch die Schnittstelle ITestElementContainerrepräsentiert, die dafür die Schnittstelle ITestElement erweitert. Analog dazu erweiterndie Schnittstellen Testkontext und Testsitzung die Behälter-Schnittstelle(ITestElementContainer), z.B. um den Zugri� auf Probanden-Projekte. Des Weiterenkönnen im Testkontext Zwischenergebnisse für einen Aktor hinterlegt werden, diese wer-den durch einen Aktor-Zustand (ITestActorState) repräsentiert. Kenntnis über den Auf-bau des Aktor-Zustands hat nur der jeweilige Aktor. Aus diesem Zusammenhang gehthervor, dass ein Kontext nur in Verbindung mit seinem Erzeuger verwendet werden kann.Wird ein Kontext einem anderen Aktor, als dem Erzeuger, zugewiesen, führt dies in derRegel zu Ausnahmefehlern. Die Testsitzung de�niert Dienste zum Zugri� auf die Testkon-�guration, dabei kann die gesamte oder nur die Aktor-eigene Kon�guration erfragt werden.Benachrichtigungen über Änderungen werden durch die Modellelemente, über den DienstnotifyChange, generiert � in Regel getrieben durch einen Wechsel der Verarbeitungszu-stände (ProgressState). Die Abbildung 4.6 zeigt die Verarbeitungszustände eines Modell-elements in Verbindung mit den erlaubten Transitionen. Nach Initialisierung eines Model-lelements ist dieses im Zustand NOT_STARTED. Durch Start eines Testlaufs erfolgt,über einen Controller (z.B. einen Aktor), der Zustandswechsel eines Modellelements in denZustand RUNNING. Für Modellelemente mit Anzeigeinformationen (z.B. Refaktorisie-rungsparameter) kann der Zustandswechsel auch direkt in den Zustand COMPLETEDerfolgen. Durch Anhalten der Verarbeitung wird ein beteiligtes Modellelement in den Zu-stand STOPPED überführt, aus dem es wieder in den Zustand RUNNING zurückge-führt werden kann. Vor dem Neustart (Reset) einer Verarbeitung werden Modellelemente,

48

4 Implementierung

Name Kardinalität BedeutungNOT_STARTED 1 Verarbeitung noch nicht begonnenCOMPLETED 2 Verarbeitung abgeschlossenRUNNING 4 in VerarbeitungSTOPPED 8 Verarbeitung angehalten

Tabelle 4.2: Verarbeitungszuständen im RTT Modell

vom Zustand COMPLETED, in den Zustand NOT_STARTED zurückversetzt. Nochlaufende Verarbeitung im Zustand RUNNING werden angehalten und vom ZustandSTOPPED in den Zustand NOT_STARTED überführt. Genau wie die Verarbeitungs-ergebnisse werden Verarbeitungszustände durch eine Aufzählung repräsentiert und könnenAnalog dazu kombiniert werden. Die Tabelle 4.2 zeigt eine Übersicht über die verfügbarenVerarbeitungszustände zusammen mit ihren Kardinalitäten und den zugeordneten Bedeu-tungen. Die Durchlaufzeiten der Verarbeitung werden vom Start bis zum Anhalten bzw.dem Verarbeitungsende gemessen. Die Wartezeiten bei Unterbrechung durch höher-prioreTasks gehen in die Messungen ein.

Weiterhin stellt die Testsitzung Filter für direkte bzw. indirekte Testziele zur Verfügung.Die indirekten Testziele sind beispielsweise anzuwendende JUnit-Testfälle die nur bei-läu�ge durch eine Refaktorisierung geändert, aber nicht als direkte Eingaben für einRefaktorisierungswerkzeug verwendet, werden sollten. Durch die Anwendung der Filterkönnen Testadapter (und Testfälle für Refaktorisierungswerkzeuge) diese Programmele-mente identi�zieren und ausschlieÿen. Bereitgestellt werden diese Filter durch Orakel, wiez.B. das semantische JUnit-Orakel. Durch Verknüpfung der bereitgestellten Filter entstehtder resultierende Filter für die direkten Testziele.

4.2.3 Kon�guration

Wie bereits angemerkt, wird die Testkon�guration durch den Launcher, als temporäreXML-Datei, erzeugt. Da der Launcher eine eigene Kon�guration besitzt, die Launch-Kon�guration, ist die Testkon�guration in diese eingebettet. Das Format der Testkon�-guration, als XML-Datei, erlaubt die Abbildung des im Unterkapitel 3.2 beschriebenenSchemas. Insbesondere ist das Format, Aufgrund der Möglichkeiten zur Strukturierungvon Daten, geeignet, um hierarchische Strukturen zu beschreiben. Die Abbildung 4.7zeigt die Schnittstelle der Testkon�guration zusammen mit der bereitgestellt Implemen-tierung als XML-Testkon�guration. Die Schnittstelle ITestConfiguration ermöglicht es,dass die Instanz einer Testkon�guration sowohl die gesamte Kon�guration als auch nureinen Teilausschnitt repräsentiert. Die gesamte Kon�guration setzt sich aus den zugrun-de liegenden Teilkon�gurationen (Probanden, Orakel und Testadapter) zusammen. DieDienste der Kon�guration erlauben die Analyse und Manipulation enthaltener Daten.Um die Testkon�guration variable zu gestalten, sind die festgelegten Tags und Attributenicht Bestandteil der Kon�guration, sondern der Testbeschreibung und als Konstanten in

49

4 Implementierung

Abbildung 4.7: Schnittstellen und Klassen der Testkon�guration

der Schnittstelle ITestDescription de�niert. Die Implementierung der Testbeschreibungkapselt den Zugri� auf die Datenstrukturen der Testkon�guration durch Bereitstellunggeeigneter Dienste. Beispielsweise ermöglicht die Implementierung der Refaktorisierungs-Testbeschreibung (RefactoringTestDescription) Testklassen aus den, in der Beschrei-bung de�nierten, Testbündeln zu laden und die enthaltenen Testfälle aufzu�nden. Hierzuverwendet die Implementierung, neben der Testkon�guration, die Java-Introspektion unddie Bündel-Classloader des OSGi-Frameworks.

Die Au�istung in Abbildung 4.8 zeigt die schematische Struktur der umgesetzten XML-Testkon�guration. Dabei beinhaltet die Sektion projects die Proband-Kon�guration. DieAufschlüsselung von Probanden-Projekten (project) erfolgt, mittels eindeutiger Schlüs-sel (ID), Anbieter (provider) spezi�sch. Teil der Probanden-ID (projectID) ist implizitdie Repository-ID. Die Aktor-Kon�guration ist Teil der Sektion actor. In dieser Sektionsind Aktoren, Orakel und Testadapter, explizit ausgewiesen. Die Steuerung des Ausnah-meverhaltens kann über den Status des Attributes continueOnError beein�usst werden.Von der Aktor-Kon�guration ausgeschlossene Programmelemente (z.B. Ressourcen) wer-den über die Tags exclude gekennzeichnet, wobei die IDs Aktor-spezi�sch interpretiertwerden. Die Testbündel-Kon�guration eines deklarativen Testadapters ist in der gleichna-migen Sektion (testbundle) aufgeführt. Die Auswahl von Testfällen erfolgt indirekt überdie Auswahl von Testklassen, so dass einzelne Testfälle nicht ausgewählt bzw. ausgeschlos-sen2 werden können.

2Auÿer durch auskommentieren der Annotationen eines Testfalls im Programm

50

4 Implementierung

1 <con f i gu ra t i on>2 <pro j e c t s >3 <prov ide r name=(providerID)>4 <pro j e c t name=(pro jec t ID )/>5 . . .6 </provider>7 . . .8 </pro j e c t s >9 <actors>

10 <ora c l e name=(orac l e ID ) continueOnError=(boolean)>11 <exc lude name=(elementID)/>12 . . .13 </orac l e>14 . . .15 <te s tadapt e r name=(tes tadapter ID ) continueOnError=(boolean)>16 <exc lude name=(elementID)/>17 . . .18 <tes tbund l e name=(bundleID)>19 <t e s t c a s e name=(classname)/>20 . . .21 </testbundle>22 . . .23 </tes tadapte r>24 . . .25 </actors>26 </con f i gu ra t i on>

Abbildung 4.8: Schematische Struktur einer XML-Testkon�guration

4.2.4 Erweiterung

Kern des RTT-Frameworks ist die Erweiterung durch neue OSGi Dienstkomponentenfür Aktoren, Repositories, Beobachter und Aktionen der Testergebnisansicht. Wie be-reits im Unterkapitel 3.6 beschrieben, bestehen Dienstkomponenten aus einer Kompo-nentenbeschreibung und einer Komponenteninstanz. Da die Komponenteninstanz durchdie Dienstkomponenten-Laufzeitumgebung bereitgestellt wird, ist für die De�nition ei-ner Komponente, neben einfachen Java-Klassen und Schnittstellen, die Komponenten-beschreibung bereitzustellen. Realisiert wird eine Komponentenbeschreibung als XML-Datei. Die Au�istung in Abbildung 4.9 zeigt die schematische Struktur einer Komponen-tenbeschreibung zur Realisierung einer RTT-Erweiterung. Zur Beschreibung einer RTT-Erweiterung muss neben der Komponenten-ID (componentID) die Implementierungsklas-se (classname) ausgewiesen und die realisierten Schnittstellen (interfacename) gekenn-zeichnet werden. Die Namen der Implementierungsklasse und der Schnittstellen sind vollquali�ziert anzugeben � d.h. der Paketname ist dem Klassen- bzw. Schnittstellennamenvoranzustellen. Zusätzlich kann der Anzeigenamen der Komponente über die Eigenschaft(engl. property) des Namen festgelegt werden. Auch weitere Eigenschaften können analogzum Anzeigenamen de�niert werden, die dann bei der Aktivierung der Komponente auszu-werten sind. Alle Eigenschaften werden als Map von Key-Wert-Paaren an die im Attributeactivate festgelegte Aktivierungsmethode übergeben. Kern der Beschreibung zur Erwei-terung des RTT ist jedoch die De�nition angebotener Schnittstellen, die über den Tagprovide der Sektion service enthalten ist. Zur erfolgreichen Instantiierung der Implemen-

51

4 Implementierung

1 <sc r : component2 xmlns : s c r="http ://www. o s g i . org /xmlns/ s c r /v1 . 1 . 0 "3 a c t i v a t e="a c t i v a t e "4 con f i gu ra t i on−po l i c y="opt i ona l "5 name=(componentID)>6 <implementation c l a s s=(classname)/>7 <se rv i c e >8 <provide i n t e r f a c e=( inter facename )/>9 . . .

10 </se rv i c e >11 <property name="name" type="St r ing " value=(displayname)/>12 . . .13 </sc r : component>

Abbildung 4.9: Schematische Struktur einer Komponentenbeschreibung zur Realisierungeiner RTT-Erweiterung

1 <sc r : component2 xmlns : s c r="http ://www. o s g i . org /xmlns/ s c r /v1 . 1 . 0 "3 a c t i v a t e="a c t i v a t e "4 con f i gu ra t i on−po l i c y="opt i ona l "5 name=(component−ID)>6 <implementation c l a s s=( c l a s s−name)/>7 <r e f e r e n c e8 bind=(bind−method )9 unbind=(unbind−method )

10 c a r d i n a l i t y = ( [ 0 . . 1 , 1 . . 1 , 0 . . n , 1 . . n ] )11 i n t e r f a c e=(requ i red−i n t e r f a c e−name)12 />13 . . .14 <se rv i c e >15 <provide i n t e r f a c e=(provided−i n t e r f a c e−name)/>16 . . .17 </se rv i c e >18 <property name="name" type="St r ing " value=(d i sp lay−name)/>19 . . .20 </sc r : component>

Abbildung 4.10: Erweiterte schematische Struktur einer Komponentenbeschreibung zurRealisierung einer RTT-Erweiterung

tierungsklasse, durch die Dienstkomponenten-Laufzeitumgebung, muss diese alle angebo-tenen Schnittstellen realisieren. Neben angebotenen Schnittstellen können Dienstkompo-nenten auch benötigte Schnittstellen referenzieren. Die Abbildung 4.10 zeigt die erwei-terte Struktur einer Komponentenbeschreibung zur Realisierung einer RTT-Erweiterung.Über den Tag reference wird eine benötigte Schnittstelle ausgewiesen. Die enthaltenenAttribute bind und unbind legen die Rückruf-Funktionen der Implementierungsklasse zumBinden und Lösen der geforderten Abhängigkeit fest. Die Kardinalität (engl. cardinality)der zu injizierenden Referenzen kann über das gleichnamige Attribute bestimmt werden.Eine Aktivierung der Dienstkomponente erfolgt erst, wenn die referenzierten Abhängig-keiten erfüllt werden können. In Tabelle 4.3 sind die verfügbaren Kardinalitäten undihren Bedeutungen aufgelistet. Die hier eingeleiteten Aspekte der Komponentenbeschrei-bung umfassen, die zur Realisierung einer RTT-Erweiterung relevanten Bestandteile und

52

4 Implementierung

Kardinalität Bedeutung0..1 Eine optionale Referenz1..1 Eine erforderliche Referenz0..n Mehrere optionale Referenzen1..n Mindestens eine erforderliche Referenz

Tabelle 4.3: Kardinalitäten für Referenzen einer Komponenten-Beschreibung

1 Manifest−Vers ion : 1 . 02 Bundle−Mani fes tVers ion : 23 Bundle−ClassPath : .4 Bundle−Act iva t i onPo l i cy : l a zy5 . . .6 Serv ice−Component : OSGI−INF/mytestadapter . xml , OSGI−INF/myoracle . xml

Abbildung 4.11: Ausschnitt einer Plugin-Manifest-Datei mit Komponentenbeschrei-bungen

beinhalten daher nur ein Untermenge der Möglichkeiten, die zur Beschreibung von Dienst-komponenten tatsächlich verfügbar sind. Eine vollständige Beschreibung, aller möglichenBestandteile, ist der OSGi Spezi�kation [17] zu entnehmen.

Damit die Dienstkomponenten-Laufzeitumgebung eine Komponente instantiieren kann,muss die Komponentenbeschreibung in der Metadatei (Manifest-Datei) eines Bündels be-kannt gemacht werden. In der Manifest-Datei werden alle hinterlegten Komponenten-beschreibungen im Eintrag Service-Component zusammengefasst. Die Abbildung 4.11zeigt einen Ausschnitt aus einer Manifest-Datei, die die Komponentenbeschreibungenmytestadapter.xml und myoracle.xml referenziert. Die Beschreibungen sind in diesemBeispiel im Ordner OSGI-INF, des Bündels zu hinterlegen. Seit Eclipse Version 3.5 sindEditoren und Assistenten zur De�nition von Komponenten im PDE enthalten, so dassdie erforderlichen Kon�gurationen über die gra�schen Ober�ächen vorgenommen werdenkönnen.

Die verbleibenden Bestandteile zur Realisierung einer Dienstkomponente sind, die in einerKomponentenbeschreibung ausgewiesenen Schnittstellen und die Implementierungsklas-se. Für RTT-Erweiterungen de�niert das Framework die anzubietenden Schnittstellenund stellt Hilfsklassen zur Realisierung bereit. Die Abbildung 4.12 stellt die Schnitt-stellen zur Realisierung von Aktoren � Orakel, Testadapter und Test-Runner � in ei-nem UML-Klassendiagramm vor. Die eingefärbten Schnittstellen, Orakel, Testadapter,Orakel-Runner und Refaktorisierungs-Test-Runner, repräsentieren die zu realisierendenSchnittstellen zur De�nition der gleichnamigen Dienstkomponenten. Die Basisschnittstel-le ITestActor fasst die Gemeinsamkeiten aller Aktoren zusammen. Neben Diensten zumZugri� auf Verwaltungsinformationen (z.B. Anzeigename oder ID) stellt die Schnittstel-le Dienste zur Erzeugung von Zustandsinformationen (ITestActorStateFactory), zumLife-Cycle-Management (ITestActivator) und zur Bestimmung anwendbarer Programm-stellen in Probanden (IElementCollector), bereit. Die Anwendung eines Aktors erfolgt

53

4 Implementierung

Abbildung 4.12: Schnittstellen zur Realisierung von Aktoren

über den Dienst apply. Die Zustandsinformationen werden zum Speichern von Zwischen-ergebnisse im Kontext verwendet. Über die Life-Cycle-Management-Schnittstelle werdenAktoren über das Starten bzw. Stoppen von Testläufen benachrichtigt. Mit Hilfe derKollektoren und Filter werden anwendbare Programmstellen in Probanden ausgewählt.Die Art der ausgewählten Elemente ist Aktor-spezi�sch, so können in den Kollektorenvon ganzen Projekten über einzelne Ressourcen bis hin zu einzelnen Programmfragmen-ten enthalten sein. Die Granularität wird durch das eingesetzte Modell (z.B. JDT) be-stimmt. Zur Unterscheidung von syntaktischen und semantischen Orakeln erweitert diegleichnamige Schnittstelle, IOracle, die Aktor-Schnittstelle, um einen Dienst zur Abfragedes Typs. Hierdurch kann ein Orakel-Runner die korrekte Ausführungsreihenfolge sicher-stellen. Auch die Schnittstelle des Testadapters, IRefactoringTestadapter, erweitert dieAktor-Schnittstelle, um einen Dienst zum Zurücksetzen von Probanden. Für denn Fall,dass das Zurücksetzen über einen Testadapter nicht möglich sein sollte, nutzt das Test-werkzeug die Dienste des Repositories, um einen Probanden in seinen Ausgangszustandzu versetzen. Insbesondere unterstützt das Framework, des RTT, Entwickler bei der Im-plementierung von neuen Aktoren, durch Bereitstellung von Hilfsklassen, die die gezeigtenSchnittstellen realisieren. Die Abbildung 4.13 zeigt die Klassen-Hierarchie der Hilfsklassenzur Realisierung von Aktoren. Die Basis-Klasse für Orakel, Testadapter und Test-Runnerimplementiert die notwendigen Schnittstellen, so dass sich Sub-Klassen auf die Umsetzungder Aktor-Logik beschränken können.

Die Schnittstelle zur Realisierung einer Repository-Anbindung wird in Abbildung 4.14gezeigt. Über die gezeigte Schnittstelle stehen Dienste zur Synchronisation, zum Abrufenund Identi�zieren von Probanden zur Verfügung. Des Weiteren de�niert die Schnittstelleeinen Dienst, mit dem ein Probanden-Projekt in seinen Ausgangszustand versetzen wer-den kann. Auf Basis der Team-Integration vereinfacht sich die Implementierung, durchAbleitung von der abstrakten Klasse TeamRepository, auf die Realisierung der Dienste

54

4 Implementierung

Abbildung 4.13: Hilfsklassen zur Realisierung von Aktoren

Abbildung 4.14: Schnittstelle zur Anbindung eines Repositories

55

4 Implementierung

Abbildung 4.15: Schnittstellen und Klassen zur Realisierung einer Modell-Beobachter--Komponente

revertChanges und refreshLocal. Zum Hinzufügen und Verwalten von Probanden wer-den im Rahmen des RTT die bereitgestellten Mittel der Team-Integration (z.B. Team-SVN) verwendet, so dass diese Schnittstelle auf De�nition dieser Dienste verzichtet.

Zur Ankopplung von Analysewerkzeugen kommt das Beobachter-Entwurfsmuster (engl.observer-pattern), aus [16], zum Einsatz. Die Abbildung 4.15 zeigt die De�nition der um-gesetzten Schnittstellen und Klassen im Framework. Die Schnittstellen IObserver undIObservable sind generisch de�niert, so dass über die Vorlageparameter eine Typisierungerfolgen kann � anders als in der Standard-Implementierung der Java-Bibliothek umge-setzt. Eine Basis-Implementierung für beobachtbare (engl. observable) Objekte oder Sub-jekte (engl. subject) beinhalten die Klassen Subject und SubjectAdapter. Die Umsetzungeines Subjektes kann durch Ableitung von der Klasse Subject realisiert werden. Ist die Ab-leitung, Aufgrund einer bereits bestehenden Hierarchie, nicht möglich, kann durch Kompo-sition mit einem Subjekt-Adapter die Umsetzung erfolgen. Die Dienstschnittstelle zur Rea-lisierung einer Modell-Beobachter-Komponente wird durch die SchnittstelleITestRunListener gestellt. Diese bindet die Vorlageparameter der BasisschnittstelleIObserver an die Schnittstellen und Klassen ITestRunListener (Beobachter),TestRootRunSession (Subject) und TestRunEvent (Argument). Das Ereignisargument

56

4 Implementierung

Abbildung 4.16: Schnittstelle zur Realisierung einer Aktion für die Testergebnisansicht

(TestRunEvent) kennzeichnet die Art der Modelländerungen (gestartet, beendet oderzurückgesetzt) und das beteiligte Modellelement. Da Beobachter-Komponenten nicht ex-plizit registriert werden, sondern implizit durch den Anwendungskern, übernimmt dieserauch die Deregistrierung. Um dennoch Speicherlöcher zu vermeiden, werden Beobachterdurch Subjekte nur schwach3 (engl. weak) referenziert � d.h. existieren im System keinestarken Referenzen auf einen Beobachter, wird dieser von der automatischen Speicherbe-reinigung (GC) freigegeben (auch ohne Deregistrierung).

Abschlieÿend kann der RTT um neue Kontext-Menü-Einträge (Aktionen) für die Tester-gebnisansicht erweitert werden, dazu ist die Realisierung der Dienstkomponenten-Schnitt-stelle IActionAdapter notwendig. Die De�nition dieser Schnittstelle ist in der Abbildung4.16 gezeigt. Die Selektionen von Modellelementen in der Testergebnisansicht werden andie Dienste isApplicable und getTarget delegiert. Über den Dienst isApplicable werdendie anwendbaren Aktionen ge�ltert. Der Dienst getTarget liefert eine auszuführende Ak-tion auf Basis der JFace-Schnittstelle IAction.

4.3 Benutzerinterface

Der Refactoring Tool Testers ist als entwicklungsbegleitendes Testwerkzeug entworfen.Die Benutzung ist der JUnit-Eclipse-Integration, durch die JDT, nachempfunden, so dasssich Entwickler, die bereits Erfahrungen mit JUnit-Plugin-Tests vorweisen können, ohnelange Einarbeitungszeit im RTT zurecht�nden. Neben der Installation des RTT, sind dieSchritte zur Erzeugung von Testprojekten, Kon�gurationen und zum Starten und Debug-gen von Testläufen im Anhang B beschrieben. Dieses Kapitel beschränkt sich daher aufdie Beschreibung der bereitgestellten Mittel zur Analyse von Testläufen � der Testergeb-nisansicht.

3Alle Objekt-Referenzen sind in Java starke Referenzen, schwache Referenzen werden durch dieKlasse WeakReference repräsentiert. Neben diesen unterscheidet Java noch SoftReference undPhantomReference, die jedoch für die RTT Implementierung nicht relevant sind.[21]

57

4 Implementierung

Zur Isolation von Tests wird ein Testlauf in einer neuen Eclipse-Instanz gestartet. Wäh-rend des Testlaufs sind Benutzerinteraktionen durch ein modales Fortschrittsfenster ge-sperrt. Der gesamte Testlauf kann jeder Zeit durch den Benutzer abgebrochen und erneutgestartet werden. Nach Abschluss eines Testlaufs stehen die Ergebnisse in der Testergeb-nisansicht, RTT Result Navigator, zur Verfügung. In der ersten Zeile der Anzeige wirdder Status des gesamten Testlaufs dargestellt, der sich aus den einzelnen Einträgen derAnzeige zusammensetzt. Die Spalten der Ansicht, aus Abbildung 4.17, beschreiben:

Abbildung 4.17: Testergebnisansicht

Label den Testfall des Refaktorisierungswerkzeug ggf. mit den verwendeten Refaktorisie-rungsparametern,

Time die Durchlaufzeit der Ausführung,

Progress-State den Verarbeitungszustand, wie beispielsweise STOPPED, RUNNINGoder COMPLETED,

Result das Verarbeitungsergebnis, wie z.B. OK, ERROR oder FAILURE. Diese wirdam Anfang der Zeile symbolisch repräsentiert. Zu Beachten ist, dass auch Ausnah-mefehler, ausgelöst durch JUnit-Testfälle, durch ERROR gekennzeichnet werden,

58

4 Implementierung

Class die Klasse des zugrunde liegenden Modellelements,

Run-Stage das Ausführungsstadium, wie z.B. Initialisierung oder Ausführung, des Mo-dellelement bzw. die Verarbeitungsphase in der es erzeugt wurde.

Des Weiteren stellt die Ansicht zur Analyse, in der Toolbar, Filter zur Verfügungen,über die die Anzeige eingeschränkt oder erweitert werden kann. Die Abbildung 4.18 zeigtdie verfügbaren Filtereinstellungen. Einträge die in der Initialisierungsphase eines Aktorserzeugt werden, sind standardmäÿig ausgeblendet. Im Fehlerfall werden diese Einträge,trotz aktiver Filtereinstellung (verbergen der Initialisierung), angezeigt. Zur Repräsenta-

Abbildung 4.18: Filter der Testergebnisansicht

tion von zusammengesetzten Testergebnissen ist die Anzeige strukturiert gewählt. DurchAufklappen eines Eintrags können die Details begutachtet werden, wie z.B. der Status derOrakel-Überprüfungen, die Eingaben und Ausgaben des Testfalls oder die modi�ziertenRessourcen. Einträge die Fehler aufweisen werden beim Expandieren automatisch bis zurFehlerquelle erweitert. Über die Option Auto-Expand, des Toolbar-Menüs, können Einträ-ge grundsätzlich vollständig erweitert werden. Jedes der Elemente der Anzeige ist durchein Modellelement repräsentiert. Einigen Modellelementen sind über das KontextmenüAktionen zugeordnet:

• TestRootContext oder RefactoringTestElement � erneutes Anwenden, der durcheinen Testfall erzeugten Refaktorisierungsbeschreibung (für den Fall, dass diese aus-geführt wurde). Vor Anwendung werden die beteiligten Probanden-Projekte in ihrenAusgangszustand versetzt,

59

4 Implementierung

• JavaTestElement � ö�nen eines JDT-Modellelements im Editor,

• DiffTestElement � ö�nen einer Ressource im Editor. Änderungen werden nursichtbar, wenn die Refaktorisierung erneut ausgeführt wurde,

• JUnitTestCaseElement � ö�nen eines JUnit-Testfalls im Editor und Ausgabe desJUnit-Exception-Stack-Trace in der Konsole,

• JavaCompileProblem � ö�nen der Fehler-Quelle im Editor,

• ExceptionTestElement � Ausgabe des Exception-Stack-Trace in der Konsole.

Des Weiteren können die Ergebnisse der Ansicht in einer Datei, in Komma-separiertem(CSV) Format, gespeichert werden. Die angewendeten Filter werden beim Exportierenberücksichtigt.

60

5 Diskussion

5.1 Interpretation und Bewertung

Mit dem Refactoring Tool Tester aus dieser Arbeit steht eine Referenzimplementierungfür das automatisierte Testen von Java-Refaktorisierungswerkzeugen in Eclipse zur Ver-fügung. Das Testwerkzeug verwendet dazu quello�ene Programme (Probanden) als Test-eingaben für Refaktorisierungswerkzeuge. Das Aufdecken von Fehlern übernehmen imRahmen des Testens Orakel, die hierzu Probanden einer syntaktischen und semantischenÜberprüfung unterziehen. Ein Vorteil des Einsatzes von quello�enen Programmen ist,dass es sich bei diesen um reale Anwendungen handelt, die eine Vielzahl der von den An-wendern verwendeten Sprachkonstrukten beinhalten und damit repräsentativ sind. Einweiterer Vorteil ist, dass viele quello�ene Programme eine hohe Testabdeckung in Formvon Regressionstests (à la JUnit) beinhalten, die zur semantischen Prüfung herangezo-gen werden können. Nachteilig ist jedoch, dass Regressionstests, als Teil der Probanden,indirekt refaktorisiert werden, wodurch der Vergleich vor und nach Refaktorisierung ggf.nicht auf der gleichen Testbasis beruht. Dabei besteht die Gefahr, dass durch fehlerhaf-te Refaktorisierungen, Fehler in Regressionstests eingeführt werden, die dann Fehler inRefaktorisierungswerkzeugen verdecken.

Kern der Implementierung des RTT ist die Umsetzung als Framework für das automa-tisierte Testen von Refaktorisierungswerkzeugen. Dabei ist das Framework nicht auf ei-ne Programmiersprache (z.B. Java) beschränkt, sondern de�niert Schnittstellen sprach-und technologieunabhängig und organisiert Implementierungsabhängigkeiten (z.B. JDT)in zentralen Paketen. Insbesondere ermöglicht die Umsetzung als Framework die Ana-lysefähigkeiten des RTT, durch Bereitstellung von Dienstkomponenten, zu erweitern �beispielsweise durch Orakel. Der deklarative Dienstansatz, des OSGi-Komponentenmo-dells, erlaubt auf elegante Weise der Dynamik des OSGi-Frameworks gerecht zu wer-den und bieten dabei den Vorteil, dass Komponenten, als einfache Java Objekte, isoliertgetestet werden können. Trotzdem kommt die Umsetzung nicht ohne den imperativenAnsatz (durch Verwendung von ServiceTracker) aus, um Dienstkomponenten auÿerhalbder Komponenten-Deklaration verfügbar zu machen. Hintergrund ist, dass die meistenEclipse-Plugins immer noch keine Dienste anbieten, sondern Erweiterungspunkte bereit-stellen, wodurch ein Teil der Eleganz wieder verloren geht. Da der deklarative DienstansatzKomponentenbeschreibungen zur De�nition von Dienstkomponenten verwendet, bestehtdie Problematik Beschreibungen und Implementierung konsistent zu halten. Durch Re-faktorisierungen, wie z.B. Rename einer Implementierungsklasse können Inkonsistenzen

61

5 Diskussion

entstehen � entsprechende Refaktorisierungswerkzeuge zur Konsistenzerhaltung fehlen inder Eclipse Version 3.5 und 3.6. Des Weiteren verwendet der RTT Contract4J zur Spe-zi�kation und Überprüfung von Invarianten, Vor- und Nachbedingungen nach Design-by-Contract (DbC). Aufgrund einer starken Verschlechterung der Performance und Er-höhung des Speicherverbrauches, durch Einsatz von Contract4J, konnte dieser Ansatznicht durchgehalten werden, so dass die umgesetzten Verhaltensspezi�kationen eher derDokumentation dienen.

Im Bezug auf die Kernfunktionalität des RTT, das automatisierte Testen von Refakto-risierungswerkzeugen, konnten durch Bereitstellung deklarativer Testadapter, die Anbin-dung von Refaktorisierungswerkzeugen stark vereinfacht werden. Dabei beinhalten wederTestfälle für Refaktorisierungswerkzeuge noch Testadapter Annahmen zum Erfolg oderMisserfolg einer Refaktorisierung � diese werden alleine durch Orakel quali�ziert. Wirdein Fehler durch einen Testfall für ein Refaktorisierungswerkzeug aufgedeckt, führt dieszum Abbruch seiner Ausführung � d.h. der RTT wechselt zum nächsten Testfall. Zu Be-rücksichtigen ist deshalb für Testfälle, anders als bei Testadaptern, dass diese nur eineinzelnes Szenario beinhalten sollten. Bei Beachtung dieses Grundsatzes reduziert sich dieLaufzeit von Tests, ohne dass weitere Szenarien unberücksichtigt bleiben.

Der Abfragewerkzeug-Testadapter bietet zudem die Möglichkeit anwendbare Programm-stellen, durch Formulierung von Abfragen auf Basis von JQuery auszuwählen und be-gegnet damit der Problemstellung der Auswahl geeigneter Refaktorisierungsparameter.Vorteil des Einsatzes von Abfragewerkzeugen ist die Ausdrucksstärke bei der Formu-lierung von Beziehungen zwischen Programmelementen, die sonst nur schwierig durchEinsatz der JDT-Search-Engine, dem JDT-Modell und das Durchlaufen der ASTs heraus-zu�ltern sind. Anderseits birgt der Einsatz von Abfragen zur Auswahl von anwendbarenProgrammstellen die Gefahr, dass die Auswahl zu spezi�sch gewählt wird, so dass nurnoch Randfälle durch die formulierten Tests berücksichtigt werden und damit der Vorteildes Einsatzes quello�ener Probanden-Projekte verloren geht � für den Fall, dass diesenicht die geforderten Sprachkonstrukte enthalten. Daher ist die Ausgewogenheit zwischengeeigneten Abfragen und verwendeten Probanden-Projekten für die Faktoren Testlaufzeitund -abdeckung entscheidend. Auch ist der Einsatz von JQuery als Abfragewerkzeug nurbedingt von Nutzen, da Abfrageergebnisse auf Basis des JDT-Modells gebunden werden,so dass das Durchlaufen der AST nicht ausbleibt, um eine feiner Granularität zu erreichen(z.B. zur Auswahl von Kontroll�ussanweisungen oder lokalen Variablen in Methoden). DesWeiteren ist die Art der Deklaration von Abfragen, als Text in Annotationen, fehleranfäl-lig, da diese keinen Gültigkeitsüberprüfungen durch einen Übersetzer unterzogen werden.Dem Benutzer steht jedoch die Möglichkeit zur Verfügung die Abfragen in der Benutzer-schnittstelle des Abfragewerkzeuges (z.B. JQuery) zu testen. Eine Weitere Fehlerquelleist jedoch das Binden von Abfrageergebnissen an Test-Methoden-Argumente (durch An-notationen), die zu Ausnahmefehlern führen kann, wenn die gewählten Datentypen nichtzuweisungskompatibel zu den Modellelementen der Abfrageergebnisse sind. Im Rahmendes Testens können jedoch Laufzeitfehler toleriert werden, da diese lediglich zum Fehl-schlag eines Tests führen und in diesem Zusammenhang behoben werden können.

62

5 Diskussion

Als entwicklungsbegleitendes Testwerkzeug ist der RTT, der Benutzung der JUnit-Eclipse-Integration, durch die JDT, nachempfunden. Zentrales Merkmal ist, dass Tests isoliert,in einer neuen Eclipse-Instanz, ausgeführt werden, so dass die produktive Umgebung vonInstabilitäten zu testender Refaktorisierungswerkzeuge unbeein�usst bleibt. Ein weitererVorteil, der sich durch die Trennung ergibt, ist, dass Tests und Refaktorisierungswerkzeugezusammen mit dem RTT Framework gedebuggt werden können � was die Fehlersuche inallen beteiligten Plugins vereinfacht. Des Weiteren stellt der RTT Mittel zur Analyse vonFehler zur Verfügung, so stehen neben Informationen zur Refaktorisierung (z.B. Refakto-risierungsparameter oder -beschreibung) Aktionen zum Nachstellen des Fehlerbildes (z.B.Wiederholen einer Refaktorisierung) zur Verfügung. Das Heraus�nden der Fehlerursacheist jedoch manuelle Aufgabe des Testentwicklers.

5.2 Vergleich mit verwandten Arbeiten

Da die Idee des automatisierten Testens von Refaktorisierungswerkzeugen nicht neu ist,existieren Testwerkzeuge, die bereits erfolgreich Fehler in den Eclipse- und NetBeans-eigenen Refaktorisierungswerkzeugen nachgewiesen haben [6]. Zur Abgrenzung zur vorlie-genden Arbeit werden die zugrunde liegenden Konzepte, des ASTGen [2] und SafeRefactor[24][23], mit denen des RTT verglichen.

Kernkonzept des ASTGen ist die Generierung von Probanden (Quellcode) für Refakto-risierungswerkzeuge. Hierzu schreiben Tester Generatoren, die die Generierung überneh-men. Zu diesem Zweck ist der ASTGen als Bibliothek von generischen, wiederverwendba-ren und kombinierbaren Generatoren geschrieben, die abstrakte Syntaxbäume erzeugen.Zur syntaktischen Überprüfung kommt der Übersetzer der integrierten Entwicklungsum-gebung, als Orakel, zum Einsatz. Die semantischen Überprüfungen erfolgen durch Anwen-dung von diversi�zierenden Tests. Zum diversi�zierenden Testen werden die generiertenASTs der gleichen Refaktorisierungen in Eclipse und NetBeans unterzogen und die Ausga-ben miteinander verglichen � Abweichung nach Refaktorisierung, durch die unterschiedlichimplementierten Refaktorisierungswerkzeuge, deuten auf Fehler hin. Der Tester muss imAnschluss feststellen welches oder welche Refaktorisierungswerkzeuge Fehler eingebrachthaben. Des Weiteren wendet ein invertierendes Orakel Gegen-Refaktorisierung zu einerRefaktorisierung an, um Änderungen rückgängig zu machen und vergleicht im Anschlussdiese Version mit der Originalen, um Fehler aufzudecken [2].

Der SafeRefactor ist als Adapter für Refaktorisierungswerkzeuge entworfen und arbeitetdaher direkt auf den produktiven Quellen von Anwendern. Auch beim SafeRefactor kommtder Übersetzer, der integrierten Entwicklungsumgebung, zur syntaktischen Überprüfungzum Einsatz. Zur semantischen Überprüfung wendet das Werkzeug JUnit-Testfälle an.Jedoch kommt SafeRefactor ohne die Bereitstellung von Testfällen durch den Benutzeraus, denn diese werden automatisch generiert. Hierzu analysiert das Werkzeug alle zurefaktorisierenden Programmstellen und identi�ziert die Methoden, die nicht von der Re-faktorisierung betro�en sind. Für die identi�zierten Methoden, die beide Versionen (vor

63

5 Diskussion

Werkzeug Testeingaben für Testverfahren zur Wiederhol-Refaktorisierungs- semantischen barkeit vonwerkzeuge Überprüfung Tests

ASTGen automatisch generierte AST diversi�zierenden Tests automatischSafe- Quellen produktiver automatisch generierte manuellRefactor Programme RegressionstestsRTT quello�ene Programme enthaltene Regressionstests automatisch

Tabelle 5.1: Gegenüberstellung der Werkzeuge ASTGen, SafeRefactor und RTT

und nach Refaktorisierung) gemeinsam haben, wählt das Werkzeug zufällig geeignete Test-eingaben aus und bestimmt die Ausgaben. Die so erzeugten Eingaben werden zusammenmit den erwarteten Ausgaben in JUnit-Testfällen festgehalten. Insbesondere nimmt sichdas Werkzeug damit der Problemstellung, die gleiche Testbasis vor und nach Refaktori-sierung zu verwenden, an [24].

Zum RTT unterscheiden sich die vorgestellten Werkzeuge in den funktionalen Aspekten,verwendete Testeingaben, verwendete Testverfahren (zur semantischen Überprüfung) undder Wiederholbarkeit von Tests. Die Tabelle 5.1 zeigt, in einer Gegenüberstellung, dieUnterschiede in den genannten Aspekten zwischen dem ASTGen, SafeRefactor und demRTT.

64

6 Schlussbetrachtungen

6.1 Zusammenfassung und Fazit

Heutige Entwicklungsumgebungen, wie z.B. Eclipse, NetBeans oder Visual-Studio, bietenWerkzeugunterstützung zur automatisierten Anwendung von Refaktorisierungen an. Vieleder existierenden Refaktorisierungswerkzeuge bleiben jedoch hinter den gestellten Erwar-tungen, so dass diese nicht korrekt Arbeiten und Fehler einführen [25]. Die Fehler, diedabei durch Anwendung von Refaktorisierungswerkzeugen in ein Programm eingeführtwerden, reichen von Übersetzungsfehlern bis hin zu Verhaltensänderungen, die besten-falls im Zuge des Testens aufgedeckt werden oder gänzlich unentdeckt bleiben. Jedenfallswird das Aufdecken von Fehlern den Benutzer der Refaktorisierungswerkzeuge überlassen.Um jedoch die Qualität von Refaktorisierungswerkzeugen nachhaltig zu verbessern, bietetsich, wie für andere Programme auch, das Testen an.

Mit dem Refactoring Tool Tester aus dieser Arbeit steht eine Referenzimplementierungfür das automatisierte Testen von Java-Refaktorisierungswerkzeugen in Eclipse zur Ver-fügung. Durch dieses Testwerkzeug können damit Fehler in Refaktorisierungswerkzeugen,mit vertretbarem Aufwand, aufgedeckt werden. Die zum Testen notwendigen repräsentati-ven Beispielprogramme (Probanden) und Regressionstests werden durch die Bereitstellungquello�ener Programme abgedeckt. Diese dienen Refaktorisierungswerkzeugen, im Rah-men des Testens, als Eingaben. Zudem nutzt der RTT die enthaltenen Regressionstestszur semantischen Überprüfungen von Probanden nach Durchführung von Refaktorisierun-gen und ist damit in der Lage ggf. eingebracht Verhaltensänderungen aufzudecken. Umeine Testkonstellation im Nachhinein auch wiederholen zu können, verwaltet der RTTProbanden und Kon�gurationen in Repositories. Mit der Umsetzung als Framework fürRefaktorisierungs-Testwerkzeuge erreicht der RTT die Erweiterbarkeit seiner Analysefä-higkeiten. Dazu weist der RTT eine komponentenbasierte Architektur auf, die dem OSGi-Komponentenmodell unterliegt. Auf dieser Basis erfolgt für den RTT die Anbindung vonzu testenden Refaktorisierungswerkzeugen � mittels Testadaptern. Des Weiteren konnteder RTT durch Bereitstellung deklarativer Testadapter die Anbindung von Refaktorisie-rungswerkzeugen stark vereinfachen. Um Tester letztendlich noch bei Auswahl geeigneterRefaktorisierungsparameter zu unterstützten, beinhaltet der RTT die Anbindung des Ab-fragewerkzeugs JQuery, das es Testern ermöglicht eine Auswahl von Programmstellen inAbfragen zu formulieren.

Als entwicklungsbegleitendes Testwerkzeug ist der RTT, der Benutzung der JUnit-Eclipse-Integration, durch die JDT, nachempfunden. Zentrales Merkmal ist, dass Tests isoliert,

65

6 Schlussbetrachtungen

in einer neuen Eclipse-Instanz, ausgeführt werden, so dass die produktive Umgebung vonInstabilitäten zu testender Refaktorisierungswerkzeuge unbeein�usst bleibt. Ein weitererVorteil, der sich durch die Trennung ergibt, ist, dass Tests und Refaktorisierungswerkzeugezusammen mit dem RTT Framework gedebuggt werden können � was die Fehlersuche inallen beteiligten Plugins vereinfacht.

Zur Evaluation der Ergebnisse, dieser Arbeit, werden die JDT-eigenen Refaktorisierungs-werkzeuge, im Rahmen einer parallelen Arbeit [9], mit dem umgesetzten Testwerkzeuguntersucht.

6.2 Ausblick

Die vom RTT bereitgestellten Mittel erö�nen die Möglichkeit zur Anbindung zukünftigerTestwerkzeuge. So könnten beispielsweise Werkzeuge zur automatischen Fehlerlokalisie-rung, z.B. EZUnit [10] oder Delta-Debugging [1], angebunden werden, um Tester bei derBestimmung von Fehlerursachen zu unterstützen. Auch die Anbindung des Testwerkzeu-ges, SafeRefactor [24], kann die Fähigkeiten des RTT bereichern, da dieser es erlaubenwürde Probanden mit keiner oder einer geringen Testabdeckung zum Testen zu verwen-den � ohne auf semantische Überprüfungen verzichten zu müssen. Des Weiteren würde derRTT für den SafeRefactor eine Testumgebung bereitstellen können, in der Tests wieder-holbar sind. Zur Ankopplung könnte beispielsweise ein deklarativer Testadapter umgesetztwerden.

Grundsätzlich bietet der Einsatz von Abfragewerkzeugen für das Testen und die Entwick-lung von Refaktorisierungswerkzeugen Vorteile, die nicht von der Hand zuweisen sind, wiez.B. die Ausdrucksstärke bei der Auswahl von Programmstellen, die mit den verfügba-ren Mitteln (z.B. JDT-Modell, AST oder -Search-Engine) sonst nur schwierig umzusetzensind (bedenkt man, dass in den Abfragen Beziehungen zwischen Programmelementen aus-gedrückt werden können). Trotzdem ist der Einsatz von JQuery als Abfragewerkzeug nurbedingt von Nutzen, da Abfrageergebnisse auf Basis des JDT-Modells gebunden werden,so dass das Durchlaufen der AST nicht ausbleibt, um eine feiner Granularität zu errei-chen (z.B. zur Auswahl von Kontroll�ussanweisungen oder lokalen Variablen in Metho-den). Von daher wäre entweder die Erweiterung von JQuery oder die Evaluation andererAbfragewerkzeuge interessant, wie beispielsweise SemmleCode [33].

Des Weiteren ist die Art der Deklaration von Abfragen, als Text in Annotationen, feh-leranfällig, da diese keinen Gültigkeitsüberprüfungen durch einen Übersetzer unterzogenwerden. Eine Weitere Fehlerquelle ist zudem das Binden von Abfrageergebnissen an Test-Methoden-Argumente (durch Annotationen), die zu Ausnahmefehlern führen kann, wenndie gewählten Datentypen nicht zuweisungskompatibel zu den Modellelementen der Ab-frageergebnisse sind. Durch Einsatz bzw. die De�nition einer Domain-spezi�schen Sprache(DSL) könnten diese Probleme angegangen werden.

66

Literaturverzeichnis

[1] Cleve, H. ; Zeller, A.: Locating causes of program failures. In: Software Enginee-ring, ICSE Proceedings 27 (2005), S. 342�351

[2] Daniel, B. ; Dig, D. ; Garcia, K. ; Marinov, D.: Automated Testing of Refacto-ring Engines. In: ESEC-FSE Proceedings 6 (2007), S. 185�194

[3] De Volder, K.: JQuery: A generic code browser with a declarative con�gurationlanguage. In: Practical Aspects of Declarative Languages (2006), S. 88�102

[4] eclipse.org (Veranst.): Eclipse IDE for Java Developers, Release Galileo. Juni 2010.� URL http://download.eclipse.org/releases/galileo

[5] Fowler, M. ; Beck, K.: Refactoring: improving the design of existing code. Addison-Wesley Professional, 1999

[6] Garcia, K.M.: TESTING THE REFACTORING ENGINE OF THE NETBEANSIDE. In: Masterarbeit University of Illinois at Urbana-Champaign (2007)

[7] Griffel, F.: Componentware-Konzepte und Techniken eines Softwareparadigmas.In: Heidelberg: dpunkt-Verlag (1998)

[8] Gruber, O. ; Hargrave, BJ ; McAffer, J. ; Rapicault, P. ; Watson, T.: TheEclipse 3.0 platform: adopting OSGi technology. In: IBM Systems Journal 44 (2005),Nr. 2, S. 289�299

[9] Ikkert, Sergei: Untersuchung der Eclipse-JDT-Refaktorisierungen mit Hilfe desRefactoring Tool Testers. In: Masterarbeit Fernuniversität in Hagen (2010)

[10] Krinke, J. ; Meyer, N. ; Steimann, F.: EZUNIT: A Framework for AssociatingFailed Unit Tests with Potential Programming Errors. In: XP Conference 8 (2007),Nr. 1.15, S. 101�104

[11] Lammert, Rainer: Component Frameworks. In: Seminar, KomponentenbasierteProgrammierung Fernuniversität in Hagen (2008)

[12] Lau, Kung-Kiu ; Wang, Zheng: Software Component Models. In: IEEE TRANS-ACTIONS ON SOFTWARE ENGINEERING 33, NO. 10 (2007)

[13] Levonyak, Markus: OSGi als Grundlage für komponentenbasierte Programmierung.In: Seminar, Komponentenbasierte Programmierung Fernuniversität in Hagen (2010)

[14] Liggesmeyer, P.: Software-Qualität. Spektrum, Akad. Verl., 2002

[15] Mansfeld, A.: Realisierung von Software-Produktlinien mit der Eclipse Rich-Client-Platform. In: Diplomarbeit Fachhochschule Giessen-Friedberg (2006)

67

Literaturverzeichnis

[16] Naftalin, M. ; Wadler, P.: Java generics and collections. O'Reilly Media, Inc.,2006

[17] OSGi Alliance (Veranst.): OSGi Service Platform Release 4 Version 4.2 CompendiumSpeci�cation. 2010. � URL http://www.osgi.org/Specifications/HomePage

[18] OSGi Alliance (Veranst.): OSGi Service Platform Release 4 Version 4.2 Core Speci-�cation. 2010. � URL http://www.osgi.org/Specifications/HomePage

[19] Polarion (Veranst.): Subversive, Subversion Team Provider for Eclipse. Juni 2010. �URL http://www.polarion.com/products/svn/subversive.php

[20] Radziwonowicz, L. ; Pavlov, R. ; Zmuda, R. ; Ziebell, S.: Unit Testingmit JUnit. In: Ausarbeitung , Methoden und Werkzeuge in der Softwareentwick-lung WS0607 (2007). � URL http://swt.cs.tu-berlin.de/lehre/mwsp/ws0607/

ausarbeitungen/Ausarbeitung-3.pdf

[21] Reichel, Peter: Realisierung einer integrierten Speicherverwaltung mit der Unter-stützung schwacher Referenzen für den Prozessor SHAP, TECHNISCHE UNIVER-SITÄT DRESDEN FAKULTÄT INFORMATIK, Diplomarbeit, 2008

[22] Shavor, S. ; Fairbrother, S. ; D'Anjou, J. ; Kehn, D.: Eclipse. Anwendungenund Plug-Ins mit Java entwickeln. Addison-Wesley, München, 2004

[23] Soares, G. ; Cavalcanti, D. ; Gheyi, R. ;Massoni, T. ; Serey, D. ; Cornélio,M.: SAFEREFACTOR�Tool for Checking Refactoring Safety.

[24] Soares, G. ; Gheyi, R. ; Serey, D. ; Massoni, T.: Making program refactoringsafer. In: IEEE Software (2010)

[25] Steimann, F.: Korrekte Refaktorisierungen: Der Bau von Refaktorisierungswerk-zeugen als eigenständige Disziplin. In: OBJEKTspektrum 4 (2010), S. 24�29.� URL http://www.sigs-datacom.de/fileadmin/user_upload/zeitschriften/

os/2010/04/steimann_OS_04_10.pdf

[26] Steimann, F. ; Keller, D. ; Aziz Safi, B.: Moderne Programmiertechniken und-methoden. In: Vorlesungsskript Fernuniversität in Hagen (2007)

[27] Szurszewski, J.: We Have Lift-o�: The Launching Framework in Eclipse. In: EclipseCorner Articles (2003). � URL http://www.eclipse.org/articles

[28] Szyperski, C. ; Bosch, J. ; Weck, W.: Component-oriented programming. In:Object-Oriented Technology ECOOP99 Workshop Reader Springer (Veranst.), 1999,S. 795�795

[29] Tavares, A.L.C. ; Valente, M.T.: A gentle introduction to OSGi. In: ACMSIGSOFT Software Engineering Notes 33 (2008), Nr. 5, S. 1�5

[30] Tigris.org (Veranst.): TortoiseSVN is an easy-to-use SCM / source control softwarefor Microsoft Windows. Juni 2010. � URL http://tortoisesvn.net/

[31] ubuntu.com (Veranst.): Ubuntu Subversion Installationhinweise. Juni 2010. � URLhttps://help.ubuntu.com/community/Subversion

68

Literaturverzeichnis

[32] University of British Columbia (Veranst.): JQuery, a query-based code browser In-stallationshinweise. Juni 2010. � URL http://jquery.cs.ubc.ca/documentation/

installation.html

[33] Verbaere, M. ; Hajiyev, E. ; De Moor, O.: Improve software quality withSemmleCode: an eclipse plugin for semantic code search. In: Conference on ObjectOriented Programming Systems Languages and Applications 22 (2007), S. 880�881

[34] Walther, T.: Architektur und Konzepte von Eclipse 3. In: Diplomarbeit FreieUniversität Berlin (2005)

[35] Weyerhäuser, M.: Die Programmierumgebung Eclipse. In: JavaSpektrum CeBIT-Sonderausgabe (2003)

69

A Paketstruktur

Die beschriebene Organisation, aus dem gleichnamigen Unterkapitel 4.1, des RTT ist inden nachfolgenden Paketen realisiert. Die Tabellen A.2, A.4 und A.6 stellen die Paketevor und beschreiben die enthaltenen Programmelemente.

Paketname Beschreibungde.fernunihagen.rtt stellt Annotationen und Klassen zur Formulierung von

Testfällen für Refaktorisierungswerkzeuge bereit.de.fernunihagen.rtt. beinhaltet die Basisschnittstellen des Testwerkzeugs,framework die beispielsweise das Modell, die Aktoren, die Test-

kon�guration, die Test-Runner und -Beobachter aus-zeichnen. Neben diesen Bestandteilen stellt das Paketedie Fassade, RTTCore, zum Zugri� auf Dienste-Kompo-nenten, auÿerhalb der Komponenten-Deklaration, bereit.

de.fernunihagen.rtt. kapselt die Klassen-Hierarchie der Aktor-unabhängigenframework.model Modellelemente.de.fernunihagen.rtt. stellt Klassen zur Verwaltung und Implementierung vonframework.oracle Orakeln, als Dienstkomponenten, bereit.de.fernunihagen.rtt. beinhaltet die Basisschnittstellen und Klassen des Test-framework.repository werkzeugs zur De�nition und Verwaltung von Repositories,

als Dienstkomponenten.de.fernunihagen.rtt. stellt Klassen zur Verwaltung und Implementierung vonframework.repository. Repositories auf Basis der Team-Integration bereit.teamde.fernunihagen.rtt. liefert die Dienstkomponente zur Ankopplung an einframework.repository. Team-SVN-Repository, unter Verwendung von Subversive.team.svnde.fernunihagen.rtt. beinhaltet den Bündel-Aktivator des SVN Konnektorframework.repository. Plugins.team.svn.internalde.fernunihagen.rtt. stellt Klassen zur Verwaltung und Implementierung vonframework.testadapter Testadaptern, als Dienstkomponenten, bereit.

Tabelle A.2: Übersicht der RTT Paketstruktur � Teil 1

70

A Paketstruktur

Paketname Beschreibungde.fernunihagen.rtt. beinhaltet Schnittstellen und Hilfsklassen, die Paket-framework.util übergreifend Verwendung �nden und von der Benutzer-

schnittstelle unabhängig sind.de.fernunihagen.rtt. beinhaltet den Bündel-Aktivator des Core-Plugins.internalde.fernunihagen.rtt. stellt die Klassen-Hierarchie der JDT-unabhängigen Filterinternal.�lter zur Verfügung.de.fernunihagen.rtt. kapselt Implementierung für Hilfsklassen und Modellele-internal.jdt mente auf Basis der JDT, beispielsweise Klassen zum

Suchen und Filtern von anwendbaren Programmstellenund Starten von JUnit4-Testläufen.

de.fernunihagen.rtt. liefert die Dienstkomponenten für das syntaktische undinternal.jdt.oracle semantische Orakel auf Basis der JDT.de.fernunihagen.rtt. beinhaltet die Implementierungen der Koordinationslogik,internal.runtime so z.B. den Anwendungskern oder die Dienstkomponen-

ten der Test-Runner (Orakel-Runner und Refaktorisier-ungs-Test-Runner).

de.fernunihagen.rtt. stellt die Klassen-Hierarchie der Testschritte (Test-internal.testadapter ProcedureStep) für deklarative Testadapter bereit.de.fernunihagen.rtt. beinhaltet alle Implementierungen von der Benutzer-internal.util schnittstelle unabhängiger Hilfsklassen, die von den JDT

unabhängig sind.de.fernunihagen.rtt. stellt Basisschnittstellen zur De�nition von Dienstkompo-ui nenten, zur Erweiterung der Ober�ächen, bereit. Beinhal-

tet die Fassade, RTTCoreUI, zum Zugri� auf Dienste-Komponenten, auÿerhalb der Komponenten-Deklaration.

de.fernunihagen.rtt. beinhaltet den Prüfstand (engl. test bench), der vomui.app Launcher verwendet wird, um Tests isoliert auszuführen.

Des Weiteren stellt das Pakete die Implementierung derLaunch-Kon�guration und des Launchers (Launch-Delegate) zur Verfügung.

de.fernunihagen.rtt. beinhaltet den Bündel-Aktivator des Testbench-Plugins.ui.app.internalde.fernunihagen.rtt. enthält die Dienstkomponente des deklarativen Abfrage-ui.testadapter.jquery. werkzeug-Testadapter auf Basis von JQuery. Beinhaltetinternal den Bündel-Aktivator des JQuery-Testadapter-Plugins.de.fernunihagen.rtt. beinhaltet den Bündel-Aktivator des UI-Plugins.ui.internal

Tabelle A.4: Übersicht der RTT Paketstruktur � Teil 2

71

A Paketstruktur

Paketname Beschreibungde.fernunihagen.rtt. enthält Implementierungen für JDT-unabhängige Aktionen,ui.internal.action als Dienstkomponenten, zur Erweiterung der Analyse-

Fähigkeiten der Ober�äche, z.B. Wiederholen einerRefaktorisierung.

de.fernunihagen.rtt. beinhaltet Implementierungen von Hilfsklassen undui.internal.jdt Aktionen, als Dienstkomponenten, auf Basis der JDT.de.fernunihagen.rtt. beinhaltet die Ober�ächen (Ansichten und Assistenten)ui.internal.jdt.launcher der Test- bzw. Launch-Kon�guration.de.fernunihagen.rtt. stellt eine Implementierungen für einen deklarativenui.internal.jdt.testadapter Java-Testadapter (ohne Abfragewerkzeug) bereit.de.fernunihagen.rtt. beinhaltet Schnittstellen und Hilfsklassen, die Paket-ui.internal.util übergreifend Verwendung �nden und von der Benutzer-

schnittstelle abhängig sind.de.fernunihagen.rtt. kapselt die Implementierung der Testergebnis-Ansicht.ui.internal.view

Tabelle A.6: Übersicht der RTT Paketstruktur � Teil 3

72

B Schnellstartanleitung

B.1 Installation und Deinstallation

B.1.1 Auslieferung

Zu der Auslieferung des Refactoring Tool Testers gehören die nachfolgenden Feature, dieüber die RTT Update-Site installiert werden können:

• RTT Core � beinhaltet die Kernbestandteile des RTT-Frameworks.

• RTT SVN Connector � stellt einen Konnektor zur Anbindung von SVN Repositorieszur Verfügung.

• RTT UI � beinhaltet alle Komponenten der Benutzerschnittstelle.

• RTT JQuery Test Adapter � enthält einen deklarativen Abfragewerkzeug-Testadapter,der JQuery verwendet (JQuery-Testadapter).

B.1.2 Voraussetzungen

Die Installation des RTT setzt folgende Umgebung voraus:

• Eclipse Java Development Tools 3.5 [4]

• Subversive SVN Team Provider (Incubation) 0.7 [4]

• Subversive SVN Connectors 2.2 [19]

• SVNKit 1.3 Implementation [19]

• JQuery Backend Plugin 4.0.3 [32]

• TortoiseSVN for Windows [30] (Optional)

Nach Installation von Eclipse können die SVN Feature über die entsprechenden Update-Sites installiert werden. Um SVN nutzen zu können, muss allerdings ein SVN-Server in-stalliert werden. Für ein Windows basiertes Zielsystem wird, zur einfachen Erzeugungund Verwaltung von SVN Repositories, der TortoiseSVN Client vorgeschlagen, mit des-sen Installation auch ein SVN-Server bereitsteht. Unter der Ubuntu Linux Distributionsteht SVN über das Software Repository bereit [31]. Zur Installation des JQuery Plug-in steht keine Update-Site zur Verfügung, bitte die Installationshinweise des Herstellersbeachten.

73

B Schnellstartanleitung

B.1.3 Installation

Der RTT kann, in der o.g. Umgebung, einfach über den Eclipse Update-Manager installiertwerden. Hierzu ist es notwendig dem Update-Manager den Ort der lokalen RTT Update-Site mitzuteilen.

Zur Installation des RTT:

1. Eclipse starten und das Menü 'Help > Install New Software...' auswählen.

Abbildung B.1: Software Updates

74

B Schnellstartanleitung

2. Über 'Add > Local' das Hauptverzeichnis der RTT-Update-Site eintragen und diegewünschten RTT-Feature auswählen.

Abbildung B.2: Installation und Feature-Auswahl

3. Mit 'Next' die Auswahl bestätigen und nach Annahme der Lizenzbedingungen dieInstallation einleiten 'Finish'.

4. Nach erfolgreicher Installation Neustart bestätigen 'Yes'.

Abbildung B.3: Installation abschlieÿen

75

B Schnellstartanleitung

B.1.4 Deinstallation

Zur Deinstallation der RTT Feature:

1. Eclipse starten und das Menü 'Help > About Eclipse...' auswählen, um zu denInstallationsdetails zu gelangen.

Abbildung B.4: About Eclipse und Installationsdetails

2. Aktion 'Installation Details' bestätigen und in der Liste 'Installed Software' diebereits installierten RTT-Feature selektieren. Eine Mehrfachauswahl ist über STRGmöglich.

Abbildung B.5: Installationsdetails

3. Über 'Uninstall' die Auswahl bestätigen.

76

B Schnellstartanleitung

4. Die Deinstallation über die Aktion 'Finish' abschlieÿen.

Abbildung B.6: Deinstallation

5. Nach erfolgreicher Deinstallation Neustart bestätigen � 'Yes'.

Abbildung B.7: Deinstallation abschlieÿen

B.2 Erzeugen von Testprojekten

Nachfolgend wird die Vorgehensweise zum Erzeugen eines Testprojektes für den JQueryTestadapter, am Beispiel eines Testfalls für das Rename-Refaktorisierungswerkzeug, vor-gestellt. Die vollständige Implementierung des Beispiels ist dem beigefügten Testprojekt-Archiv zu entnehmen. Die Vorgehensweise zum Import eines existierenden Projektes auseinem Projekt-Archiv ist im Abschnitt B.3.1 in den Schritte 1-3 beschrieben.

77

B Schnellstartanleitung

Zur Erstellung eines Testprojektes:

1. Eclipse starten und das Menü 'File > New > Project ...' auswählen, um zum Dialog'New Project' zu gelangen.

Abbildung B.8: Erzeugen eines Projektes

2. Den Eintrag 'Plug-in Project' auswählen und mit 'Next' bestätigen.

Abbildung B.9: Erzeugen eines Plugin-Projektes

78

B Schnellstartanleitung

3. Im Dialog 'New Plug-in Project' den geeigneten Projektnamen vorgeben und mit'Next' bestätigen.

Abbildung B.10: Einstellungen eines Plugin-Projektes

4. Die Optionen 'Generate an activator ...' und 'This plug-in will make contributionsto the UI' können deaktiviert werden. Anschlieÿend das Erzeugen des Projektes mit'Finish' einleiten.

Abbildung B.11: Inhalt eines Plugin-Projektes

79

B Schnellstartanleitung

5. Im Manifest Editor das Tab 'Dependencies' aktivieren und über die Aktion 'Add'die Abhängigkeit auf das RTT Core Plug-in (de.fernunihagen.rtt) einfügen.

Abbildung B.12: Abhängigkeit auf RTT Core Plugin

6. Über das Menü 'File > New > Class' einen Test Klasse für die zu implementierendenTestfälle erzeugen.

Abbildung B.13: Test-Klasse erzeugen

80

B Schnellstartanleitung

7. Im Dialog 'New Java Class' einen geeigneten Namen für die Test-Klasse vorgebenund mit 'Finish' die Erzeugung einleiten.

Abbildung B.14: Informationen der Test-Klasse festlegen

8. In den Editor wechseln, um mit der Codierung der Testfälle zu beginnen.

B.3 Erzeugen von Kon�gurationen

B.3.1 Bereitstellung von Probanden-Projekten

Nach der erfolgreichen Installation des RTT und der Einrichtung eines SVN Repositories,sind vor einem Testlauf noch Probanden bereitzustellen. Als Proband kommt jedes be-liebige Eclipse Java-Projekt für den RTT in Frage. Eclipse Java-Projekte, die bereits ineinem SVN Repository verwaltet sind, benötigen keine Vorbereitung um als Probanden zufungieren � für diese Projekte können die nachfolgenden Schritte übersprungen werden.

Im nachfolgenden Beispiel dient ein, speziell für das Testprojekt des Rename-Refaktor-isierungswerkzeugs, vorbereitetes Java-Projekt als Testeingabe. Die Schritte 1-3 beschrei-ben den Vorgang des Imports dieses Java-Projektes aus dem beigefügten Projekt-Archiv.Falls das Projekt bereits im Workspace vorliegt können diese Schritte übersprungen wer-den.

81

B Schnellstartanleitung

Zur Vorbereitung eines neuen Probanden:

1. Eclipse starten und 'File > Import' auswählen.

Abbildung B.15: Import Aktion

2. Die Import Aktion in der Kategorie 'General > Existing Projekt into Workspace'auswählen und mit 'Next' bestätigen.

Abbildung B.16: Import eines bestehenden Projektes

82

B Schnellstartanleitung

3. Im Feld 'Select archive �le' den Pfad zum Eclipse Java-Projekt-Archiv angeben undnach Selektion der zu importierenden Projekte im Archiv, den Import über 'Finish'anstoÿen.

Abbildung B.17: Import aus einem Projekt-Archiv

83

B Schnellstartanleitung

4. Das importierte Projekt imWorkspace auswählen und über das Kontextmenü 'Team> Share Project ...' die Verknüpfung zu einem Team Repository aufbauen.

Abbildung B.18: Projekt mit Repository verknüpfen

5. Im Dialog 'Share Project' den SVN Connector auswählen und die Selektion mit'Next' bestätigen.

Abbildung B.19: SVN Connector Auswahl

84

B Schnellstartanleitung

6. Im Dialog 'Share Project Wizard' die URL des SVN Repository ausweisen und mit'Next' bestätigen.

Abbildung B.20: Repository Informationen festlegen

7. Die Aktion 'Share Project' mit 'Finish' abschlieÿen.

8. Die Übergabe des Projektes im Dialog 'Commit' bestätigen.

Abbildung B.21: Initialer Commit

85

B Schnellstartanleitung

9. Abschlieÿend steht das Projekt zur Selektion innerhalb einer RTT-Testkon�gurationzur Verfügung � womit die Vorbereitungen erfolgreich abgeschlossen sind.

10. Die Aktionen 1-9 zur Vorbereitung weitere Probanden wiederholen.

B.3.2 Launch-Kon�guration

Über die Launch-Kon�guration des RTT wird die notwendige Testkon�guration für einenTestlauf erzeugt. Notwendige Bestandteile für eine Testkon�guration sind:

• das Testprojekt für das zu testende Refaktorisierungswerkzeug

• und die vorbereiteten Probanden.

Zum erzeugen einer neuen Lauch-Kon�guration:

1. Eclipse starten und in das Workspace wechseln, in dem die vorbereiteten Projektevorliegen.

2. Das Testprojekt selektieren und über das Kontextmenü 'Run as > Run Con�gura-tions...' auswählen.

Abbildung B.22: Launch-Kon�guration ö�nen

86

B Schnellstartanleitung

3. Aus der Liste der verfügbaren Kon�gurationstypen 'RTT Java' auswählen und überdas Kontextmenü 'RTT Java > New' eine neue Kon�guration erzeugen.

Abbildung B.23: Testkon�guration erzeugen

4. Im Tab 'Test' der Kon�guration das Test-Projekt auswählen.

Abbildung B.24: Auswahl des Testprojektes

5. Im Baum der Testprojekt-Kon�guration erscheinen die verfügbaren Test-Klassen, in

87

B Schnellstartanleitung

denen Testfälle enthalten sind. Durch Selektion bzw. Deselektion von Test-Klassenkönnen enthaltene Testfällen ausgeschlossen werden.

6. Zum Ausschluss von Ressourcen aus Probanden (Test-Subject), für den jeweiligenTest-Aktor, in der Spalte der Testadapter oder Orakel, entsprechende Ressourcen se-lektieren. In der Standardauswahl sind alle Ressourcen enthalten. Die aktuelle Aus-wahl kann durch speichern 'Test-Subject Con�gurations > Toolbar' als Standard-kon�guration im Probanden-Projekt hinterlegt werden, so dass für neue Launch-Kon�gurationen mit demselben Probanden-Projekt die Einstellungen übernommenwerden. Zu Beachten ist, dass im Baum der Probanden-Kon�guration jeweils nurdie, für den Test-Aktor, anwendbare Ressourcen auswählbar sind.

Abbildung B.25: Aktor-Kon�guration eines Probanden

88

B Schnellstartanleitung

7. Über das Kontextmenü im Baum der Probanden-Kon�guration oder der Toolbarkönnen Projekte hinzugefügt oder entfernt werden. In der Projekt-Auswahl erschei-nen im Workspace enthaltene Java-Projekte, die nicht bereits in der Kon�gurationenthalten sind und erfolgreich vorbereite wurden. 1

Abbildung B.26: Hinzufügen von Probanden zur Kon�guration

8. Die Standard Launch-Kon�gurationseinstellungen wie z.B. Main, Arguments oderCommon können über die gleichnamigen Tabs verändert werden, so z.B. die Auswahldes Workspace oder der Speicherort der RTT Launch-Kon�guration.

9. Nach erfolgreicher Kon�guration kann über 'Run' ein Testlauf gestartet werden, derin einer neuen Eclipse Instanz ausgeführt wird.

Anmerkung Nach Erzeugung einer Launch-Kon�guration dürfen die Probanden aus demWorkspace entfernt werden. Vor einer erneuten Veränderung der Launch-Kon�gu-ration werden diese dann ggf. automatisch abgerufen.

B.4 Debuggen

Um ein Testfall zu Debuggen muss eine Launch-Kon�guration im Debug-Mode gestartetwerden. Die Schritte zur Erzeugung der Launch-Kon�guration sind im Abschnitt B.3.21In der vorliegenden Version sind Plugin-Projekte ausgeschlossen

89

B Schnellstartanleitung

beschrieben. Zum starten eines Testfalls im Debug-Mode:

1. Eclipse starten und in das Workspace wechseln, in dem die vorbereiteten Projektevorliegen.

2. Das Testprojekt selektieren und über das Kontextmenü 'Debug as > Debug Con�-gurations...' auswählen.

3. Die zuvor erzeugte Launch-Kon�guration auswählen.

4. Über 'Debug' den Testlauf im Debug-Mode aktivieren.

Um in das RTT-Framework zu Debuggen müssen die Quell-Projekte des RTT vor demLaunch ins Workspace importiert werden, aus dem der Launch gestartet wird. Dort könnendann etwaige Brechpunkte gesetzt werden.

90

C CD Inhaltsverzeichnis

Die beiliegende CD beinhaltet nachfolgende Verzeichnisse und Dateien:

Gröÿe Name Beschreibung2,5M ausarbeitung.pdf das Dokument der Ausarbeitung im PDF-

Formatdoc/ das Verzeichnis der API-Beschreibung des

RTT bzw. seiner Plugins � generiert durchJavaDoc als HTML-Dateien

jquery/ das JQuery-Backend-Plugin18M rtt_projects.zip das Archiv mit Plugin-Projekten zum RTT

und JQuery9,5K rtt_quickstart_examples.zip das Archiv mit Beispiel-Projekten der

Schnellstartanleitungupdatesite/ die lokale Update-Site des RTT zur Instal-

lation der erforderlichen Plugins und Fea-ture über den Eclipse-Update-Manager

91