Analyse der Einsatzmöglichkeiten automatisierter Softwaretests auf Basis von JUnit, Selenium und Hudson

Aus Winfwiki

Wechseln zu: Navigation, Suche
Name des Autors / der Autoren: Michaela Neuhaus, Amir Dabaghzadeh
Titel der Arbeit: "Analyse der Einsatzmöglichkeiten automatisierter Softwaretests auf Basis von JUnit, Selenium und Hudson"
Hochschule und Studienort: FOM Hamburg

Inhaltsverzeichnis




1 Einleitung

Der rasante technologische Fortschritt in den vergangenen zehn Jahren ermöglicht den Einsatz immer anspruchsvoller werdender Softwaresysteme. Dies gewährt ein Abbilden komplexer Geschäftsprozesse, führt aber auch zu einem Anwachsen der Anforderungen an die eingesetzte Software und an das Testen dieser Software. Softwaretests, die für die Sicherstellung der immer bedeutender werdenden Qualität von Software unumgänglich sind, werden aufgrund des Zeitaufwands häufig nur als Kostenfaktor gesehen. Mit steigendem Umfang von Sourcecode und Technologieeinsatz, erhöht sich die Komplexität der Anwendungsprogramme und die Schwierigkeit der Fehlererkennung und Fehlerbehebung. Dies stellt eine zusätzliche Herausforderung an das Testen selbst dar. Ein Automatisieren von Softwaretests wird auf vielen Ebenen den wachsenden Anfoderungen an das Testen gerecht. Mit Hilfe dieses neuen Testvorgehens wird eine konstante Qualität geliefert und Zeit gespart, da hunderte von Tests in nur wenigen Minuten durchlaufen werden. Die kontinuierliche Durchführung von automatisierten Tests stellt sicher, dass neu erstellter Code fehlerfrei ist und keine Fehler in den bereits vorhandenen Code einschleust. Deshalb sollte von Anfang an darauf geachtet werden einen hohen Grad an Testabdeckung aufrecht zu erhalten.

Ziel dieser Arbeit ist es die Möglichkeiten und Vorteile von automatisierten Softwaretests aufzuzeigen und einen Überblick über die wichtigsten Komponenten der vorgestellten Produkte JUnit, Selenium und Hudson zu vermitteln.

2 Grundlagen

2.1 Build

Während der Softwareentwicklung werden verschiedene Versionen der Software festgehalten. Diese Versionen werden als Build bezeichnet. Von den Anfängen der Entwicklung bis zum marktreifen Produkt durchläuft eine Software meist die folgenden Versionen: Alphaversion, Betaversion, Release Candidate und Final[1].

2.2 Fehler

Ein Fehler ist nach DIN 55350 Teil 11 bzw. DIN EN ISO 8402 die Nichterfüllung einer festgelegten Forderung[2].

2.3 Framework

Als Framework wird in der Softwareentwicklung ein Rahmenwerk bezeichnet, das eine wiederverwendbare Architektur vorgibt. Diese besteht in der objektorientierten Softwareentwicklung aus Klassen und Methoden, die beliebig angepasst und erweitert werden können. Der Einsatz von Frameworks spart Entwicklungszeit und stellt meistens eine gute Basis für Weiterentwicklungen dar[3].

2.4 Graphical User Interface Test (GUI)

Bei einem GUI-Test wird das Graphical User Interface (GUI), d.h. die Benutzeroberfläche einer Anwendung, getestet. Diese Tests simulieren einen Benutzer, der sich mit Hilfe der Maus durch eine Anwendung klickt und über die Tastatur Eingaben macht. Diese Tests prüfen, ob die Anwendung nach einer Aktion wie erwartet reagiert[4].

2.5 Reflections

Java-Mechanismus, der zur Laufzeit den Zugriff auf Klassen und Objekte ermöglicht[5].

2.6 Software-Qualität

Nach DIN ISO 9126 versteht man unter Software-Qualität die Gesamtheit der Merkmale und Merkmalswerte eines Software-Produkts, die sich auf dessen Eignung beziehen, festgelegte Anforderungen zu erfüllen[6]

2.7 Source Code Management System

Mit einem Source Code Management System werden die verschiedenen Versionen der entwickelten Software durch den Einsatz einer Datenbank verwaltet. Der zentrale Aufbewahrungsort der Daten wird als Repository bezeichnet[7].

2.8 Testautomatisierung

Durch den Einsatz von Testautomatisierung wird der Versuch unternommen manuelles Testen überflüssig zu machen. Im Rahmen der Automatisierung von Testvorgängen können arbeitsintensive und wiederkehrende Testdurchläufe dem Entwickler abgenommen werden. Das Testen ist dadurch häufiger, zuverlässiger und diversifizierter möglich. Dadurch werden dem Entwickler Freiräume geschaffen, die er für weitere Qualität sichernde Maßnahmen nutzen kann. Wird konsequent auf Testautomatisierung gesetzt, sind Kostensenkungen möglich[8].

2.9 Testen

Mit dem Wort 'testen' wird ein Prüfverfahren beschrieben, mit dem codierte Programme auf korrekte Formulierung und Ausführung geprüft werden[9]. Das Ziel der Durchführung von Tests ist es, Fehlfunktionen sichtbar zu machen. Ein erfolgreicher Test dokumentiert, unter welchen Bedingungen die Software das Resultat liefert, das gemäß Spezifikation erwartet wird[10].

3 Analyse und Einsatz von automatisierter Softwaretests

3.1 Notwendigkeit von Softwaretests

In Anlehnung an: http://www.agitar.com/solutions/why_unit_testing.html (09.01.2010 17:50)Abb. 1 Kostenverlauf der Fehlerbehebung
In Anlehnung an: http://www.agitar.com/solutions/why_unit_testing.html (09.01.2010 17:50)
Abb. 1 Kostenverlauf der Fehlerbehebung

Es gibt kaum noch Organisationen die ohne Software auskommen. Auch die meisten Geräte und Maschinen in unserer Umwelt werden mit Mikroprozessoren und deren Software betrieben. Die Qualität von Software ist also zu einem entscheidenden Faktor im Wettbewerb geworden[11].
Dem steht gegenüber, dass kein konstruktives Verfahren die Entstehung von fehlerfreier Software garantieren kann. Der größte Teil der Kosten für die Entwicklung einer Software fallen in der Wartungsphase eines im Markt befindlichen Produktes an. Ursache dafür sind Fehler in der Software, die während der Entwicklung entstanden sind, jedoch erst nach der Einführung bei der Produktnutzung aufgefallen sind. Mit zunehmender Komplexität wächst auch die Schwierigkeit Fehler im Nachhinein zu korrigieren. Schlecht strukturierte und unzureichend dokumentierte Softwareprojekte erschweren die Fehlersuche und bergen die Gefahr der Folgefehler.
Den damit entstehenden Kosten kann nur durch Softwaretests und anschließende Fehlerbeseitigung bereits während der Entwicklung entgegengewirkt werden[12]. Daher werden in vielen Organisationen zunehmend Maßnahmen getroffen, um die Qualität von Software durch systematische Prüfungen und Tests zu erhöhen[13].

3.2 Notwendigkeit von Testautomatisierung

Ein häufiges Testvorgehen in der Softwareentwicklung ist der Vergleich der Programmausgaben mit den Erwartungen durch den Entwickler. Auch sogenannte Schreibtischtests, also die statische Analyse von Quellcode beim Lesen, sind üblich. Jedoch sind beide Vorgehensweisen unzureichend. Denn das Ziel von Softwaretests muss das Erzeugen von reproduzierbaren Ergebnissen auf Basis von klar definierten Vorgehensmodellen sein[14].

Testautomatisierung erfüllt die genannten Anforderungen, des Weiteren hilft sie die Qualität zu erhöhen, Risiken zu reduzieren und die Erstellung und Wartbarkeit, sowohl von Testcode als auch von zu testendem Code zu reduzieren[15].

3.3 Anforderungen an Testautomatisierungs-Frameworks

Eine sehr gute und vielfach erprobte Basis für automatisierte Softwaretests stellen Testautomatisierungs-Frameworks dar[16]. Doch auch diese Art von Framework kann mehr oder weniger gut geeignet sein. Daher stellt Link fünf Anforderungen an Testautomatisierungs-Frameworks[17], aus denen die anschließend aufgelisteten Vorteile resultieren:

  1. Die Sprache zur Testspezifikation ist die Programmiersprache selbst.
    • Sowohl Anwendungscode als auch Testcode können so mit den gleichen Werkzeugen geschrieben werden.
    • Geringe Einarbeitungszeit in das Framework.
    • Der Entwickler braucht beim Wechsel zwischen Anwendungscode und Testcode nicht umdenken.
  2. Anwendungscode und Testcode müssen getrennt werden können.
    • Somit vergrößert sich nur der Testcode, nicht der Anwendungscode.
    • Test- und Anwendungscode können bei der Auslieferung sauber getrennt werden.
    • Die Struktur des Testcodes ist unabhängig von der des Anwendungscodes.
  3. Die Ausführung einzelner Testfälle ist voneinander unabhängig.
    • Abhängigkeiten unter den einzelnen Testfällen oder die Notwendigkeit der Einhaltung einer Ausführungsreihenfolge sind damit ausgeschlossen.
    • Es können bei Bedarf und zur Zeitersparnis Einzel-Testfälle ausgeführt werden.
  4. Testfälle können beliebig zu Testsuiten zusammengefasst werden.
    • Zusammengehörige Tests können damit sinnvoll gruppiert werden.
  5. Der Erfolg oder Misserfolg der Testausführung sollte auf einen Blick erkennbar sein.
    • Ein Testprotokoll in Form einer Systemdatei ist daher ungeeignet und steht einer grafisch aufbereiteten Darstellung nach.

4 Analyse und Einsatz der konkreten Produkte

Die im Folgenden vorgestellten Testautomatisierung-Frameworks JUnit und Selenium erfüllen die zuvor in Kapitel 3.3 genannten Anforderungen. Da der Fokus von JUnit auf Modultests und der von Selenium auf GUI-Tests liegt, bilden sie eine ideale Ergänzung. Erweitert um Hudson, einem Werkzeug zur Unterstützung kontinuierlicher Integration, wird eine Testautomatisierungs-Umgebung geschaffen, die Java-Entwickler unterstützt ihre Entwicklungstätigkeit möglichst effizient voranzutreiben und dennoch für eine hohe Testabdeckung des entwickelten Quellcodes und somit zu einer Steigerung der Software-Qualität zu sorgen.

JUnit Selenium Hudson
Unit-Test X
Integrationstest X
GUI-Test X
Kontinuierliche Integration mit automatischer Testausführung (X) (X) X

Tabelle1: Einsatzzweck / Software

4.1 Unit-Test und Integrationstest mit JUnit

Da sich Unit-Tests und Integrationstests lediglich darin unterscheiden ob Wechselwirkungen zu anderen Modulen bestehen, aber in der Durchführung und dem Konzept in JUnit identisch sind, können die folgenden Punkte dieses Abschnitts für beide Testarten angewandt werden.

4.1.1 Zweck

Unit-Tests prüfen eine Einheit dahingehend, ob sie die in der Spezifikation geforderte Funktionalität vollständig und korrekt erfüllt. Funktionalität ist bei Unit-Test gleichbedeutend mit Ein-/Ausgabeverhalten der zu prüfenden Einheit. Dabei wird jede Einheit isoliert getestet um sicher zu stellen, dass andere Einheiten keinen Einfluss auf das Verhalten der zu prüfenden Einheit haben und somit ein Fehler klar zu zuordnen ist[18].
Der Integrationstest hingegen prüft das Zusammenspiel von Einheiten und deren Wechselwirkung[19].
Sowohl Unit-Tests als auch Integrationstests werden an den Schnittstellen der zu prüfenden Einheit durchgeführt[20].

4.1.2 Aufbau des Frameworks

Im Folgenden werden vier Komponenten vorgestellt, anhand derer der Testablauf verständlich gemacht werden kann.

4.1.2.1 Testtreiber
Quelle: eigene DarstellungAbb. 2 JUnit Testtreiber der Eclipse SDK
Quelle: eigene Darstellung
Abb. 2 JUnit Testtreiber der Eclipse SDK

Das Herzstück von JUnit ist der Testtreiber (engl. testrunner), der die einzelnen Testklassen mit ihren Testmethoden aufruft, die Soll-Reaktionen erfasst und protokolliert[21]. JUnit bietet in der Version 3.8 drei unterschiedliche Testtreiber an, die zur Ausführung von JUnit-Tests genutzt werden können. Diese unterscheiden sich lediglich in der Darstellung des Testergebnisses, jedoch nicht in der Durchführung dieser:

  • junit.textui.TestRunner() - gibt die Ergebnisse als Text auf der Standardausgabe aus.
  • junit.awtui.TestRunner() - einfach gehaltene GUI Darstellung.
  • junit.swing.TestRunner() - komplexe GUI Darstellung.

Da JUnit im Java-Umfeld zum Quasi-Standard für Unit-Tests geworden ist, haben einige Entwicklungsumgebungen eigene, voll integrierte Testtreiber. Beispielhaft ist die Entwicklungsumgebung Eclipse zu nennen (siehe Abbildung 2)[22].

4.1.2.2 Testfall

JUnit-Testfälle werden als Methoden in Java-Klassen implementiert, die von junit.framework.TestCase erben. Dabei werden in der Regel mehrere Testfälle in einer Testklasse zusammengefasst. Jeder Testfall bildet ein Szenario ab, an dessen Ende ein oder mehrere Werte gegen einen Soll-Wert geprüft werden. Damit der Testtreiber die auszuführenden Testklassen automatisch finden kann, müssen diese laut Konvention in ihrer Bezeichnung die Endung "Test" haben. Zwecks einfacherer Zuordnung wird empfohlen, die Testklassen genauso zu benennen wie die zu testende Klasse, erweitert um die vom Testtreiber benötigte Endung. Demzufolge müsste zu einer Klasse mit der Bezeichnung "Konto" eine zugehörige Testklasse mit der Bezeichnung "KontoTest" existieren[23].

Auch die Testfälle müssen Konventionen entsprechen damit sie automatisch gefunden werden. Falls nicht anders definiert, werden alle Methoden, die sowohl nicht statisch, öffentlich als auch parameterlos sind und in der Bezeichnung mit "test" beginnen als JUnit Testfall betrachtet[24].

Mehrere Testklassen können zu einer Suite zusammengefasst werden. So können beispielsweise Testklassen, die die Geschäftslogik testen, von GUI-Testklassen getrennt werden. Dazu muss eine Instanz der Klasse TestSuite() erzeugt und dieser die benötigten Testklassen mit der Methode add() übergeben werden[25].

4.1.2.3 Prüfung

Der Mechanismus, mit dem JUnit den Erfolg oder Misserfolg eines Tests prüft, wird Assert (dt. Behauptung) genannt. Ein Assert vergleicht zum Testzeitpunkt den Ist-Zustand eines Wertes mit einem vorgegebenen Soll-Zustand. In der JUnit-Superklasse Assert() sind eine Reihe von unterschiedlichen Asserts implementiert, die an die Klassen TestCase() und TestSuite() vererbt werden und dementsprechend auch von allen JUnit-Testklassen geerbt und genutzt werden können.

Beispiel:

  • assertEquals(Soll-Wert, Ist-Wert)
    Prüft, ob der vorgegebene Soll-Wert und der abgefragte Ist-Wert gleich sind.
  • assertEquals(Fehlermeldungstext, Soll-Wert, Ist-Wert)
    Dieses in der Signatur erweiterte Assert bietet die Möglichkeit eine Fehlermeldung als Übergabeparameter zu übergeben, der im Falle eines Misserfolges im Resultat angezeigt wird und die Fehlersuche beschleunigen soll.

Einige weitere Beispiele für Asserts:

  • assertTrue(Zustand)
    Prüft, ob der entgegengenommene Zustand wahr ist.
  • assertFalse(Zustand)
    Prüft, ob der entgegengenommene Zustand nicht wahr ist.
  • assertNotNull(Objekt)
    Prüft, ob das Objekt null ist.
  • assertSame(Objekt1, Objekt2)
    Prüft, ob es sich bei den übergebenen Objekten um das selbe handelt.

In einem Testfall können beliebig viele Asserts eingebunden werden. Sofern eine der in einem Testfall durchgeführten Prüfungen fehl schlägt, gilt der gesamte Testfall als Misserfolg[26].

4.1.2.4 Testergebnis

Eine Instanz der Klasse TestResult() dient als Datenhalter und Steuerungsinstanz der ausgeführten Tests. In ihr werden beispielsweise alle Testfälle, deren Durchführung misslang, und Testfälle, die zu unerwarteten Fehlersituationen geführt haben, gesammelt. Aus den gesammelten Daten wird nach Beendigung aller Testfälle das Testergebnis ermittelt [27].

Testergebnisse werden unterschieden in[28]:

  • run - für erfolgreich durchgelaufene Tests
  • failure - für fehlgeschlagene Tests
  • error - für Testfälle, die zu einer unbehandelten Exception führen

4.1.3 Ablauf

Quelle: in Anlehnung an Link (2005), Seite 93Abb. 3 Sequenzdiagramm Ablauf von JUnit Testdurchführung
Quelle: in Anlehnung an Link (2005), Seite 93
Abb. 3 Sequenzdiagramm Ablauf von JUnit Testdurchführung

Nach dem Starten eines Testfalls oder einer Test-Suite wird zunächst eine Instanz der Klasse TestRunner erzeugt, in der die Testergebnisse gespeichert werden. Die Instanz der Klasse TestRunner wird einer Test-Suite übergeben, die jeden Testfall einzeln ausführt. Das Ausführen eines Testfalls beginnt mit dem Aufruf der Methode setUp(). Diese Methode wird vor jedem Testfall ausgeführt und sorgt bei entsprechender Implementation dafür, dass bei jedem Testlauf gleiche Voraussetzungen vorherrschen. Dies ist insbesondere notwendig, um auf keine feste Reihenfolge in Ausführung von Testfällen angewiesen zu sein. Nach Abschluss der setUp-Methode wird der eigentliche Testfall ausgeführt, in dem mindestens eine Prüfung durch einen Assert durchgeführt werden sollte, und das Ergebnis in dem TestRunner-Objekt gespeichert. Nach Beendigung des Testfalls wird, falls vorhanden, die Methode tearDown() der Testklasse aufgerufen, mit der der Entwickler die Möglichkeit hat reservierte Ressourcen wieder freizugeben und den Ausgangszustand wieder herzustellen. Da davon ausgegangen wird, dass alle Testfälle in einer Testklasse dieselben Voraussetzungen und Objekte benötigen, gibt es für jede Testklasse gemeinsame setUp() und tearDown() Methoden[29].

Die GUI-Varianten des Testtreibers stellen den Testfortschritt anhand eines grünen Balkens dar, der sobald ein Test fehlschlägt oder zu einem Error führt rot leuchtet. Getreu dem Leitspruch: "keep the bar green to keep the code clean".

4.1.4 Testfallerstellung

Quelle: eigene DarstellungAbb. 4 Assistent zur Erzeugung einer JUnit-Testklasse in Eclipse
Quelle: eigene Darstellung
Abb. 4 Assistent zur Erzeugung einer JUnit-Testklasse in Eclipse

JUnit-Testfälle werden als Java-Klassen implementiert. Um die Übersichtlichkeit zu bewahren sollte jede Testklasse nur das Verhalten einer Klasse testen[30]. Eclipse SDK bietet einen Assistenten zur Testfallerstellung an (siehe Abbildung 4).
Die Testfallerstellung wird im Folgenden an hand eines Beispiels verdeutlicht.
Beispiel-Interface der zu prüfenden Klasse "Uberweisungsservice":

public interface Ueberweisungsservice {

	/**
	 * überweist den angegebenen Betrag vom Konto des Senders auf das Konto des Empfängers. 
	 * 
	 * @param sender Konto des Senders
	 * @param empfaenger Konto des Empfaengers
	 * @param betrag Der zu überweisende Betrag
	 * @return gibt zurück ob die Überweisung erfolgreich war
	 */
	boolean ueberweise(Konto sender, Konto empfaenger, double betrag);
}


Beispiel-Implementierung der Java-Klasse "UeberweisungsserviceTest", mit der die Klasse "UeberweisungsserviceImpl" am Interface "Ueberweisungsservice" getestet wird:

import junit.framework.TestCase;


public class UeberweisungsserviceTest extends TestCase {

	private Konto konto1 = new Konto();
	private Konto konto2 = new Konto();
	private Ueberweisungsservice ueberweisungsservice = new UeberweisungsserviceImpl();
	
	/**
	 * initialisiert die Konten mit einem Saldo und einem Dispo.
	 */
	public void setUp(){
		
		// Konto 1
		konto1.setKontonummer(10);
		konto1.setSaldo(100.00);
		konto1.setDispo(20.00);
		
		// Konto 2
		konto2.setKontonummer(11);
		konto2.setSaldo(100.00);
		konto2.setDispo(20.00);
	}
	
	/**
	 * prüft ob eine korrekte Überweisung möglich ist (HappyPath).
	 */
	public void testUberweisungHappyPath(){
		ueberweisungsservice.ueberweise(konto1, konto2, 10.00);
		assertEquals("Sender konnte nicht an Empfänger ueberweisen!",90.00, konto1.getSaldo());
		assertEquals("Sender konnte nicht an Empfänger ueberweisen!",110.00, konto2.getSaldo());
	}
	
	/**
	 * prüft ob es möglich ist auf das selbe Konto zu überweisen.
	 */
	public void testUberweisungGleichesKonto(){
		boolean result = ueberweisungsservice.ueberweise(konto1, konto1, 10.00);
		assertFalse("Sender konnte Betrag auf Senderkonto ueberweisen!", result);
	}
	
	/**
	 * prüft ob es möglich ist einen negativen Betrag zu überweisen.
	 */
	public void testUberweisungNegativerBetrag(){
		ueberweisungsservice.ueberweise(konto1, konto2, -10.00);
		assertEquals("Sender konnte negativen Betrag ueberwiesen!",100.00, konto1.getSaldo());
		assertEquals("Sender konnte negativen Betrag ueberwiesen!",100.00, konto2.getSaldo());
	}
	
	/**
	 * prüft ob es mögich ist einen höheren Betrag als Saldo+Dispo zu überweisen.
	 */
	public void testUberweisungUberDeckung(){
		ueberweisungsservice.ueberweise(konto1, konto2, 150.00);
		assertEquals("Sender konnte hoeher als Saldo+Dispo ueberweisen!",100.00, konto1.getSaldo());
	}
	
	/**
	 * prüft ob es möglich ist einen Betrag zu überweisen, der über den Guthaben (Saldo) liegt,
	 * aber nicht das Dispo übersteigt.
	 */
	public void testUberweisungUberSaldo(){
		ueberweisungsservice.ueberweise(konto1, konto2, 110.00);
		assertEquals(-10.00, konto1.getSaldo());
		assertEquals(210.00, konto2.getSaldo());
	}
}

4.1.5 Grenzen

Ohne Anwendung von Java.Reflections können nur public- und protected-Methoden getestet werden. Letztere setzen des Weiteren voraus, dass die Testklassen in der Paketstruktur dem gleichen Package zugeordnet sind.

4.2 GUI-Test mit Selenium

4.2.1 Zweck

Bei einem GUI-Test mit Selenium werden sowohl die Benutzeroberflächen-Funktionalitäten (Buttons, Eingabefelder etc.) eines Web-Frontends getestet als auch dessen Workflows überprüft[31].

4.2.2 Anwendung

Selenium ist ein Testframework, mit dem automatisierte GUI-Tests von browserbasierten Anwendungen durchgeführt werden können. Das Programm ist als Open-Source-Software frei und kostenlos unter der Apache 2.0 Lizenz erhältlich[32]. Selenium verwendet die eigene Sprache Selense, auf die in Kapitel 4.2.4 näher eingegangen wird. Selenium kann in vier nachfolgend beschriebene Hauptmodule unterteilt werden[33]:

  • Selenium Core
  • Selenium Integrated Development Environment (IDE)
  • Selenium Remote Control (RC)
  • Selenium Grid
4.2.2.1 Selenium Core

Das Modul Selenium Core ist das Herzstück von Selenium. Es stellt eine JavaScript Bibliothek zur Verfügung, die den anderen Selenium Modulen als Basis dient und daher die Grundlage für alle auf Selenium basierenden Softwaretests ist.

Das Selenium Core Modul kann aber auch separat, ohne zusätzliche Ergänzungen zum Ausführen von Testsuiten verwendet werden[34]. Zur Ausführung von Testsuiten wird nur der TestRunner angeboten, der im Aufbau einer auf Frames basierenden HTML-Seite entspricht. Dies ist möglich, da die Testsuiten für Selenium Core im HTML-Format gespeichert werden.

Die Ausführung des TestRunners erfolgt in einem Browser und unterliegt somit den Einschränkungen der Same Origin Policy[35]. Diese begrenzt die Zugriffsmöglichkeiten von Javascript und untersagt den Wechsel zwischen Domains, Ports und Protokollen[36].

Abbildung 5 zeigt den Startbildschirm der mitgelieferten Testsuite, die in der Datei TestSuite.html gespeichert ist. Abbildung 6 zeigt die Ergebnisse der Testsuite mit einigen fehlgeschlagenen Tests.

Quelle: eigene DarstellungAbb. 5 Selenium Core mit der TestSuite "TestSuite.html"
Quelle: eigene Darstellung
Abb. 5 Selenium Core mit der TestSuite "TestSuite.html"
Quelle: eigene DarstellungAbb. 6 Testergebnisse der Testsuite "TestSuite.html" im TestRunner
Quelle: eigene Darstellung
Abb. 6 Testergebnisse der Testsuite "TestSuite.html" im TestRunner
4.2.2.2 Selenium Integrated Development Environment (IDE)

Selenium IDE ist eine integrierte Entwicklungsumgebung für Selenium Testsuiten und ist als Plug-In für den Mozilla Firefox[37] realisiert. Es stellt damit, in Zusammenarbeit mit dem Browser, eine vollständige Entwicklungsumgebung für Selenium-Tests zur Verfügung und bietet die Möglichkeit Selenium-Tests automatisch aufzuzeichnen, zu editieren und wieder abzuspielen[38]. Im Kapitel 4.2.3 werden die Erstellung von Testfällen und die Verwendung von Selenium IDE erläutert.

4.2.2.3 Selenium Remote Control (RC)
In Anlehnung an: Selenium (o.D.)Abb. 7 Übersicht über die Verwendung von Selenium RC im Driven Mode
In Anlehnung an: Selenium (o.D.)
Abb. 7 Übersicht über die Verwendung von Selenium RC im Driven Mode

Das Modul Selenium RC dient der Fernsteuerung (Remote Control) von Selenium-Tests. Das Modul besteht aus zwei Teilen[39]:

  • Sprachbibliotheken - für die verwendeten Programmier- und Script-Sprachen
  • dem Selenium Server - zur Fernsteuerung von Browsern und als Proxy


Der Selenium RC Server wird auf einem entfernten Rechner installiert, auf dem die Tests ausgeführt werden. Die Testausführung wird durch den Selenium RC Client aus der Ferne gesteuert. Die Testergebnisse des Servers werden direkt an den Client zurückgegeben. Auf dem Server müssen neben dem Selenium RC Server Modul alle für die Tests notwendigen Browser installiert werden. Durch die Integration einer breiten Palette von APIs und Sprachbibliotheken für HTML, Java, C#, Perl, PHP, Python und Ruby bietet dieses Modul ein Höchstmaß an Flexibilität und Erweiterbarkeit[40].

Der Selenium RC Server kann in zwei Modi ausgeführt werden:
1. Interactive Mode
Durch das Ausführen des folgenden Befehls wird der Selenium RC Server im Interactive Mode gestartet:

 java -jar selenium-server.jar -interactive

Läuft der Selenium RC Server im Interactive Mode werden die Kommandos jeweils einzeln in die Kommandozeile eingegeben. Dadurch ist ein Beobachten der Bearbeitung der einzelnen Schritte im Browser möglich. Folgender Aufruf startet den Browser Internet Explorer mit der URL:http:www.google.de

 cmd=getNewBrowserSession&1=*iexplore&2=http://www.google.de

Es können die Browser Firefox, Internet Explorer und Opera direkt über die Parameter *firefox, *iexplore und *opera gestartet werden. Das Starten andere Browser ist über den Parameter *custom und die Pfadangabe zu dem installierten Browser möglich. Durch die integrierte Proxyfunktionalität, kann beim Starten einer externen Anwendung die Same Origin Policy umgangen werden. Der Wechsel der Verbindung von http auf https führt jedoch erneut zu einer Verletzung der Sicherheitsregel und kann auch mit der Proxyfunktion nicht umgangen werden. Ist ein häufiger Wechsel zwischen den Protokollen unumgänglich kann auf experimentelle Browser zurückgegriffen werden. Über den Parameter *iehta und *chrome[41] werden die Browser Internet Explorer und Firefox in einem speziellen Modus ohne Proxyfunktionalität gestartet wodurch die Same Origin Policy umgangen wird[42].

2. Driven Mode
Standardmäßig wird Selenium RC im Driven Mode gestartet. Im Gegensatz zum Interactive Mode werden die Kommandos im Driven Mode per http an den Selenium Server übermittelt und müssen nicht manuell an der Konsole eingegeben werden. Der große Vorteil ist hierbei die Flexibilität der Clients, von denen aus die Tests durchgeführt werden, denn als Voraussetzung muss nur eine http Verbindung zu dem Selenium Server aufgebaut werden[43].

4.2.2.4 Selenium Grid
Quelle: eigene DarstellungAbb. 8 Selenium Grid steuert das gleichzeitige Ausführen von Tests auf mehreren Remote Control Servern
Quelle: eigene Darstellung
Abb. 8 Selenium Grid steuert das gleichzeitige Ausführen von Tests auf mehreren Remote Control Servern
Selenium Grid ist eine weitere Ausbaustufe des Selenium Remote Control. Das Modul beschleunigt die Ausführung von Tests und macht die Infrastruktur mit den beteiligten Rechnern transparenter. Der Selenium Grid Server koordiniert die parallelen Ausführungen von Tests auf den unterschiedlichen Selenium Servern durch den Einsatz des Selenium Hubs. Dieser steuert zentral die http Anfragen an die unterschiedlichen Selenium Server und leitet die Rückantworten an die richtige Stelle weiter. Auf diese Weise ist es möglich nicht nur einzelne Tests, sondern auch Testsuiten parallel auf den verschiedenen Servern abzuarbeiten. Gestartet wird der Selenium Hub über folgenden Aufruf:
ant launch-hub

Voraussetzung ist die Installation von Java, Apache ANT und der Selenium Grid Software. Nach dem Starten ist die Weboberfläche über die Adresse URL:http://localhost:4444/console erreichbar und liefert eine Übersicht über die konfigurierten Umgebungen, verfügbare Remote Clients und aktive Remote Clients. Auf den Remote Clients erfolgt der Start über den Aufruf:

ant launch-remote-control

Auf der Selenium Grid Hub Konsole kann die Anmeldung des Clients überprüft werden (siehe Abbildung 9). Durch die Übergabe von Umgebungsparametern und deren Konfiguration in der Datei grid_configuration.yml kann gezielt gesteuert werden, auf welchem Selenium Server und mit welchem Browser ein Test durchgeführt werden soll. Die Übergabe der Umgebungsparameter erfolgt beim Client Start über den Parameter Denvironment[44]:

ant -Denvironment="Firefox auf Windows Vista" launch-remote-control
Quelle: eigene DarstellungAbb. 9 Selenium Grib Hub Konsole
Quelle: eigene Darstellung
Abb. 9 Selenium Grib Hub Konsole

4.2.3 Testfallerstellung

Quelle: eigene DarstellungAbb. 10 Selenium IDE
Quelle: eigene Darstellung
Abb. 10 Selenium IDE

Das Erstellen von Testfällen kann durch die Aufnahmefunktion der Selenium IDE oder manuell geschehen. Bei der manuellen Variante wird, wie beim Programmieren, von einem Entwickler Code geschrieben, der aus Kommandos, Eingaben und Abfragen besteht. Der Code kann in HTML, Selenese oder einer der unterstützten Programmiersprachen, beispielsweise Java, geschrieben werden. Bei einer Implementierung in Java lassen sich die Selenium Testfälle in JUnit ausführen[45].

Eine weitere Variante Testfälle zu erstellen ist die Aufnahmefunktion von Selenium IDE[46]. Sie zeichnet im Record-Mode alle Aktionen auf, die in der Webanwendung durchgeführten werden. Die Überprüfung des konkreten Inhalts von Ausgaben, wie beispielsweise die angezeigten Texten, geschieht über Assertions die über das Kontextmenü eingerichtet werden. Ein typisches Beispiel für eine solche Assertion ist die Überprüfung der korrekten Anrede eines Kunden, der sich auf einem Webportal angemeldet hat. In dem Selenium IDE-Fenster werden unter dem Reiter Table die einzelnen Testschritte im Selense-Format aufgelistet. Über die Textfelder "Command", "Target" und "Value" können die Testschritte manuell bearbeitet werden. Das Kontextmenü bietet weitere Funktionen, wie das Löschen und das Einfügen weiterer Testschritte. Selenium IDE speichert die Testfälle im HTML-Format. Mit der Exportfunktion werden Testfälle in die Formate Java, C#, Perl, PHP, Python und Ruby konvertiert[47].


HTML-Code eines Beispieltests:

  • Suchen über www.google.de nach "selenium"
  • Auswahl des ersten Treffers "Selenium web application testing system"
  • Auswahl des Links "Lern more"
  • Überprüfung des Textes "Selenium IDE"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="http://www.google.de/" />
<title>New Test</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">New Test</td></tr>
</thead><tbody>
<tr>
	<td>open</td>
	<td>/search?hl=de&source=hp&q=selenium&meta=&btnG=Google-Suche</td>
	<td></td>
</tr>
<tr>
	<td>clickAndWait</td>
	<td>btnG</td>
	<td></td>
</tr>
<tr>
	<td>clickAndWait</td>
	<td>//div[@id='res']/div[1]/ol/li[1]/h3/a/em</td>
	<td></td>
</tr>
<tr>
	<td>clickAndWait</td>
	<td>link=Learn more</td>
	<td></td>
</tr>
<tr>
	<td>verifyTextPresent</td>
	<td>Selenium IDE</td>
	<td></td>
</tr>

</tbody></table>
</body>
</html>

Java Implementierung des obigen Beispiels

package com.example.tests;

import com.thoughtworks.selenium.*;
import java.util.regex.Pattern;

public class selenium test extends SeleneseTestCase {
	public void setUp() throws Exception {
		setUp("http://www.google.de/", "*chrome");
	}
	public void testSelenium test() throws Exception {
		selenium.open("/");
		selenium.type("q", "selenium");
		selenium.click("btnG");
		selenium.waitForPageToLoad("30000");
		selenium.click("link=Selenium web application testing system");
		selenium.waitForPageToLoad("30000");
		selenium.click("link=Learn more");
		selenium.waitForPageToLoad("30000");
		verifyTrue(selenium.isTextPresent("Selenium IDE"));
	}
}


Mehrere Testfälle können zu einer Testsuite zusammengefasst werden. Testsuiten werden im HTML-Format gespeichert. Über die Exportfunktion können die Formate Java, C#, Perl, PHP, Python und Ruby gewählt werden.

Das Abspielen der Testfälle erfolgt auf dem unter "Base URL" konfigurierten Host. Durch das Ändern der Base URL ist es möglich den gespeicherten Test auf einem anderen Hosts abzuspielen. Der Testfortschritt kann im Selenium IDE Testeditor verfolgt werden. Der aktuelle Testschritt wird gelb hinterlegt. Erfolgreich ausgeführte Testsschritte werden grün, fehlgeschlagene rot dargestellt. Abbildung 10 zeigt einen erfolgreich durchgeführten Test. Die Ausführung eines Tests kann, ähnlich einem Debugger, schrittweise erfolgen. Dabei ist es möglich die Ausführung an einer bestimmten Stelle zu unterbrechen. Dies erfolgt über die Funktion "Toggle Breakpoint". Der Test wird erst nach Aktion durch den Benutzer fortgesetzt. Über die Funktion "Set / Clear Start Point" ist es möglich einen neuen Startpunkt innerhalb eines bestehenden Testes zu definieren. Während des Abspielens eines Testfalls werden alle Schritte und die dazugehörenden Ergebnisse über die IDE protokolliert. Das Ergebnis dieses Loggings wird in der Log-Konsole angezeigt[48].

4.2.4 Selense

Selense kann in die Kategorien Actions, Accessors,Assertions und Element Locators eingeteilt werden[49].

  • Actions:
Bei den Action-Kommandos handelt es sich um Befehle, die Benutzerinteraktionen auf der zu testenden Webseite ausführen. Diese manipulieren den Zustand einer Webseite und konfigurieren das Abspielen des Selenium Tests.
Kategorie Kommandos
Maus click, doubleClick, mouseDown, mouseUp, mouseMove, mouseOver, mouseOut, dragAndDrop, setMouseSpeed
Tastatur keyDown, keyUp, keyPress, altKeyDown, altKeyUp, typeKeys
Eingabefelder select, addSelection, removeSelection, check, uncheck, type, setCursorPosition, submit
Browser open, openWindows, selectWindows, selectFrame, windowsFocus, windowsMaximize, goBack, refresh, createCookie, deleteCookie
Tabelle 2 Übersicht über die Action-Kommandos
Jeder Action der Kategorien Maus, Tastatur und Eingabe kann das Suffix "AndWait" angehängt werden, um nach der ausgeführten Aktion auf das Laden einer neuen Seite zu warten[50].
  • Accessors:
Accessor-Kommandos untersuchen den momentanen Zustand einer Webseite, extrahieren einen bestimmten Teil und speichern diesen in einer Variable[51].
  • Assertions:
Bei Assertions handelt es sich um Zusicherungen, die einen erwarteten Wert mit dem vorhandenen Wert vergleichen. Assertions basieren auf Accessors. Assertions können die Kommandos verify, assert, waitFor sowie deren Negationen aufrufen[52].
  • Element Locators
Ein Element Locator beschreibt das Ziel und definiert das Element auf einer Webseite, auf das sich ein Selenium Kommando bezieht. Selense stellt die Element Locators identifier, id, name, link, dom, xpath und css zur Verfügung[53].
Zur Erklärung der einzelnen Element Locators wird folgendes Beispiel verwendet:
Ansicht HTML-Quellcode: Ansicht im Web-Browser:
<html>
  <body>
   <form id="loginForm">
    <input name="username" type="text" />
    <input name="password" type="password" />
    <input name="continue" type="submit" value="Login" />
    <input name="continue" type="button" value="Clear" />
    <p>Are you sure you want to do this?</p>
    <a href="continue.html">Continue</a>
    <a href="cancel.html">Cancel</a>
   </form>
 </body>
 <html>
Quelle: eigene DarstellungAbb. 1 Ansicht im Web-Browser
Die Locator id und name beziehen sich direkt auf die gleichnamigen Attribute im HTML-Quellcode. Die Textfelder des Beispielcodes können über "name=username" und "name=password" angesprochen werden. Der Locator identifier hingegen sucht zuerst nach einem Element anhand des HTML-Attributes id und anschließend nach dem HTML-Attribute name und liefert in diesem Beispiel folgende Ergebnisse[54]:
  • identifier=loginForm
  • identifier=username
  • identifier=password
  • identifier=continue
  • identifier=continue
Der Locator link sucht im Dokument nach einem Link mit dem angegebenen Text. Der Locator "link=Continue" findet im Beispiel den Verweis auf continue.html.
Der Typbezeichner dom steht als Abkürzung für Document Object Model und wurde von dem Word Wide Web Consortium (W3C) entwickelt. Es handelt sich dabei um einen Standard der beschreibt, wie auf Elemente in HTML-Seiten über Objekte zugegriffen wird[55]. Der Zugriff erfolgt über JavaSkript:
  • dom=document.getElementById('loginForm')
  • dom=document.forms['loginForm']
Der Typbezeichner xpath ist wie dom ein Standard des W3C und steht für XML Path Language[56]. Xpath wird zum Ansprechen von Elementen verwendet, wenn keine geeignete id oder name Attribute vorhanden sind. Xpath kann mit absoluten oder relativen Bedingungen verwendet werden. Bei den absoluten Xpath Bedingungen werden alle Objekte nach dem <html>-Tag angegeben, z.B. xpath=/html/body/form[1][57].
Beispiele für relative Bedingungen sind:
  • xpath=//form[1] - bezeichnet das erste Form-Element
  • xpath=//form[@id='loginForm'] - bezeichnet das Form-Element, für das id='loginForm' gilt
Der Locator css steht für Cascading Style Sheets und ist wie dom und xpath ein durch das W3C entwickelter Standard[58]. Css spürt Elemente über die CSS Selector Syntax auf[59]:
  • css=form#loginForm
  • css=input[name="username"]

4.3 Kontinuierliche Integration/Tests mit Hudson

Quelle: eigene DarstellungAbb. 11 Konfigurationsoberfläche Hudson
Quelle: eigene Darstellung
Abb. 11 Konfigurationsoberfläche Hudson
Hudson ist eine Open Source Software zur Kontinuierlichen Integration. Durch seine schnell wachsende, globale Anhängerschaft wurden bereits viele Erweiterungen und Schnittstellen geschaffen. Es werden pro Woche ca. 4.000 Downloads und insgesamt 20.000 aktive Installationen gezählt[60].

4.3.1 Zweck

Die Integration von Programmmodulen ist nicht trivial und kann zu unterschiedlichsten Fehlersituationen führen. Hudson versetzt Softwareentwickler in die Lage, mehrmals täglich ihren Programmcode zu integrieren, somit möglichst frühzeitig auf Probleme aufmerksam zu werden und dadurch Zeit zu sparen. Hudson führt automatisch Builds und Tests durch. An einem Web-Frontend erfolgt eine grafisch aufbereitete Darstellung der Testergebnisse, ergänzt um Statistiken und anderen Metriken[61].

4.3.2 Anwendung

Hudson ist nach dem Download des Programmpakets "hudson.war" mit wenigen Handgriffen aufgesetzt und bedarf keiner Installation. Unter der Voraussetzung, dass eine Java Laufzeitumgebung auf dem Rechner installiert ist, reicht der Kommandozeilen-Aufruf:

$ java -jar hudson.war

aufzurufen. Die weitere Bedienung und Konfiguration kann direkt im Web-Frontend von Hudson über http://localhost:8080 oder in XML-Konfigurationsdateien durchgeführt werden.

4.3.3 Projekte

Quelle: http://wiki.hudson-ci.org/display/HUDSON/Meet+Hudson (09.01.2010 17:51)Abb. 12 Übersicht über die Projekte
Quelle: http://wiki.hudson-ci.org/display/HUDSON/Meet+Hudson (09.01.2010 17:51)
Abb. 12 Übersicht über die Projekte

Alle Aufgaben in Hudson werden über Projekte und Jobs verwaltet. Hudson unterscheidet zwischen den nachfolgend beschriebenen vier verschiedenen Profilen.

4.3.3.1 Externen Job überwachen

Über dieses Profil erfolgt die Überwachung von Prozessen, die außerhalb von Hudson laufen. Über das Webinterface sind nur die Angabe eines Jobnamens sowie einer Beschreibung möglich. Die Konfiguration des Jobs erfolgt über die Eingabeaufforderung:

set HUDSON_HOME=http://localhost:8080/
java -jar \path\to\WEB-INF\lib\hudson-core-*.jar "job name" cmd.exe /c <program>
4.3.3.2 Maven

Mit Auswahl dieses Profils wird ein Maven 2 Projekt erstellt. Hudson verwendet zur Konfiguration die POM Dateien des Maven Projektes wodurch der Konfigurationsaufwand vermindert wird. Dieser Jobtyp befindet sich noch in der Entwicklungsphase, kann aber bereits verwendet werden.

4.3.3.3 Free Style

Dies ist das meistgenutzte Profil in Hudson und wird für alle weiteren Projekte verwendet. Bei der Konfiguration kann zwischen verschiedenen Build Tools gewählt werden.

4.3.3.4 Multikonfigurationsprojekt

Ebenso wie der Free Style Typ kann bei diesem Projekt zwischen verschiedenen Build Tools gewählt werden. Das Multikonfigurationsprojekt ist für Projekte geeignet, die in unterschiedlichen Umgebungen getestet und plattformspezifisch erstellt werden müssen. Über die Konfiguration von Achsen ist es möglich verschiedene Umgebungsparameter zu übergeben. Zum Testen einer Datenbankanwendung mit den Datenbanksystemen MySQL, PostgreSQL und Oracle wird eine Variable "database" erstellt, welche für jedes Build mit einer anderen Umgebungsvariable gefüllt wird. Durch die Konfiguration einer weiteren Achse, beispielsweise jdk5 und jdk6, werden bei einem Build alle möglichen Konfigurationen ausgeführt und 3*2=6 Builds erstellt.

jdk=[JDK5,JDK6], database=[mysql,postgresql,oracle]
4.3.3.5 Konfigurationsmöglichkeiten

Durch die Entwicklung von Plug-Ins werden die Funktionalitäten und Einsatzmöglichkeiten von Hudson kontinuierlich erweitert. Zurzeit sind bereits über 160 Plug-Ins verfügbar[62]. Für die Projekttypen Free Style, Maven2 und Multikonfigurationsprojekt können weitere Konfigurationen vorgenommen werden. Hudson unterstützt standardmäßig die Source Code Management Systeme CVS und Subversion. Durch die Integration von Plug-Ins kann die Unterstützung für die Systeme Accurev, Bitkeeper, ClearCase, Git, Mercurial, Perforce, StarTeam und weitere Systeme hinzugefügt werden. Zu den unterstützten Build Tools zählen Ant, Maven, Shell Skripte und Windows Batch Kommandos. Durch Plug-Ins können weitere Build Tools, wie beispielsweise Gant, Gradle, Grails, Kundo, Selenium und Ruby verwendet werden. Als Build Trigger können beispielsweise via IRC, Ivy, Jabber oder Join empfangene Nachrichten verwendet werden. Mit Hilfe der Überwachungsfunktion werden Ergebnisse komfortabel per E-Mail oder RSS Feed an die Entwickler versendet. Mit Hilfe der Build Report Funktion können Berichte zu den durchlaufenen Tests erstellt und die Ergebnisse grafisch dargestellt werden. Mit distributed builds wurde die Möglichkeit geschaffen, den Build und die Tests auf freigeschalteten Workstations durchzuführen. Dadurch werden einerseits die zur Verfügung stehende, freie Rechenkapazität optimal ausgelastet. Andererseits können auf diese Weise auch Tests auf unterschiedlichen Betriebssystemen, mit verschiedenen Entwicklungsumgebungen und Datenbanken durchgeführt werden[63].

4.3.3.6 Testergebnis
Quelle: eigene DarstellungAbb. 13 Build Verlauf
Quelle: eigene Darstellung
Abb. 13 Build Verlauf
Quelle: eigene DarstellungAbb. 14 Trend der Testergebnisse
Quelle: eigene Darstellung
Abb. 14 Trend der Testergebnisse

Mit dem Build Verlauf stellt Hudson eine Übersicht zur Verfügung, in der auf einem Blick die Anzahl und das Ergebnis der durchgeführten Builds zu einem Projekt angezeigt werden.
Über unterschiedliche Farben wird der Status zu dem jeweiligen Build angezeigt:

Das Projekt wurde noch nie gebaut oder wurde deaktiviert
Der letzte Buid war erfolgreich
Der letzte Build war erfolgreich aber instabil. Dies bedeutet, dass der Build zwar technisch durchgeführt werden konnte, dabei aber Tests während des Builds fehlschlugen.
Der letzte Build schlug fehl

Das Icon neben dem Build-Verlauf gibt Ausschluss über den Stabilität des gesamten Projektes. Die Stabilität wird in fünf Bereiche gestaffelt:

Mindestens 80% der Builds waren erfolgreich.
Mindestens 60% aber weniger als 80% der Builds waren erfolgreich.
Mindestens 40% aber weniger als 60% der Builds waren erfolgreich.
Mindestens 20% aber weniger als 40% der Builds waren erfolgreich.
Weniger als 20% der Builds waren erfolgreich.

In der Trend-Ansicht wird grafisch der Verlauf der verschiedenen Builds für ein Projekt dargestellt.

4.4 Das Ziel

4.4.1 Testautomatisierung nach Fowler

In seinem Artikel "Continuous Integration" beschreibt Martin Fowler beispielhaft, welchen Einfluss unter anderem automatisierte Softwaretests auf seine tägliche Entwicklungstätigkeit haben[64]. In dem von ihm aufgegriffenen Beispiel möchte er einer bestehenden Software eine neue Funktion hinzufügen und macht damit die Vorteile von automatisierten Softwaretests deutlich.

Zunächst lädt er eine Arbeitskopie des Codes der zu erweiternden Software auf seinen Arbeitsrechner. Der Code des aktuellen Entwicklungsstandes wird für alle Entwickler des Projekts auf einem zentralen Archivierungsserver bereitgestellt.

Im nächsten Schritt werden die Funktionalität vom Entwickler implementiert und automatisierte Testfälle geschrieben, die sicherstellen sollen, dass die neue Funktionalität korrekt funktioniert und den gestellten Anforderungen entspricht.

Nach der Kompilierung des gesamten Codes können die Testfälle durch Knopfdruck automatisch ausgeführt werden. Falls das Kompilieren oder die Durchführung eines der Testfälle fehlschlägt, muss solange nachgebessert werden, bis der Fehler behoben ist und alle Testfälle erfolgreich durchgeführt werden können.

Erst wenn das Kompilieren und die Testdurchführung auf dem Arbeitsrechner erfolgreich waren, können die Änderungen auf den zentralen Archivierungsserver eingespielt werden. Die Gefahr ist nun, dass in der Zwischenzeit von anderen Entwicklern Änderungen auf dem Archivierungsserver hoch geladen wurden, die mit seinen Änderungen kollidieren. Um dies festzustellen, müssen die aktuellen Änderungen vom Archivierungsserver geladen und auf dem Arbeitsrechner neu kompiliert und getestet werden. Falls dabei keine Fehler auftreten, kann der lokale Stand auf den Archivierungsserver gespielt werden.

Nun geht der Testprozess auf einer zentralen Maschine, die den Integrationsprozess unterstützen soll, weiter. Diese wird über Änderungen der Software auf dem Archivierungsserver informiert und lädt sich den letzten Stand der Software, um ihn neu zu kompilieren und automatisch alle vorhandenen Testfälle durchzuführen. Falls es zu Fehlern beim Kompilieren oder Testen kommt, wird der Entwickler, der den letzten Stand eingespielt hat, informiert und steht in der Verantwortung das Problem umgehend zu beheben.

4.4.2 Umsetzung mit JUnit, Selenium und Hudson

In einer Umgebung, wie sie von Fowler im Beispiel beschrieben wurde, wird jeder neue Code mindestens zwei Mal automatisch getestet, bis die neue Funktionalität in den bestehenden Teil der Software übergehen kann. Da automatisierte Tests mit einem Knopfdruck gestartet und nach wenigen Augenblicken ein Resultat liefern, wird deren Durchführung von dem Entwickler nicht als lästig empfunden. Die Durchführung von manuellen Tests wäre ungleich aufwändiger, zeitraubender und Qualitätsschwankungen unterworfen. Die Testfälle bleiben auch nach der Integration auf dem Server bestehen und werden bei jeder weiteren Integration ausgeführt um zu überprüfen, ob der bestehende Code durch das Einbinden neuer Module Schaden nimmt.

Eine derartige Umgebung und das beschriebene Vorgehen lassen sich auch mit JUnit, Selenium und Hudson realisieren. Wie in Kapitel 4.3.3.5 beschrieben ist durch die Integration der Plug-Ins, dass Ausführen von Selenium- und JUnit-Tests durch Hudson möglich. Der Ablauf wird in Abbildung 15 dargestellt.


Quelle: eigene Darstellung
Abb. 15 Zusammenspiel Hudson, Selenium und Junit

5 Fazit

Softwaretests sind unumgänglich, denn Software, die nicht systematisch und gründlich getestet wurde, birgt ein großes Risikopotential. Die Einführung eines automatisierten Softwaretestsystems ist zunächst mit Aufwand und Kosten verbunden. Dem gegenüber steht der Anspruch an die Softwarequalität, welche durch den Einsatz von Testautomatisierungs-Frameworks gewährleistet wird, da sie die Testdurchführung vereinheitlicht und vereinfacht. Dies sorgt für eine Steigerung der Qualität und Wartbarkeit der Software. So gehen Softwareprojekte mit einem hohen Grad an Testabdeckung nur ein sehr geringes Risiko ein, dass durch nachträgliche Änderungen und Erweiterungen, bestehende Teile des Softwareprojekts Schaden nehmen könnten. Die in dieser Arbeit vorgestellten Softwareprodukte JUnit, Selenium und Hudson sind ausgereift, vielfach erprobt und werden ständig weiterentwickelt. Durch deren kombinierten Einsatz können Softwareprojekte auf Knopfdruck durchgängig getestet werden. Des Weiteren kann ein System zur kontinuierlichen Integration und Testdurchführung dazu beitragen, einen Überblick über die Entwicklung und die Stabilität des Projekts zu erhalten. Durch die daraus resultierenden Kosteneinsparungen und bei gleichzeitig steigender Qualität, ist ein relativ hoher Grad an Wirtschaftlichkeit von Softwareprojekten sichergestellt.


6 Abkürzungsverzeichnis

API Application Programming Interface
CVS Concurrent Version System
CSS Cascading Style Sheets
DIN Deutsches Institut für Normung e. V.
DOM Document Object Model
EN Europäische Norm
GUI Graphical User Interface
IDE Integrated Development Environment
ISO International Standards Organisation
RC Remote Control
W3C World Wide Web Consortium
XPATH XML Path Language

7 Abbildungsverzeichnis

Abb.-Nr. Abbildung
1 Kostenverlauf der Fehlerbehebung
2 JUnit Testtreiber der Eclipse SDK
3 Sequenzdiagramm Ablauf von JUnit Testdurchführung
4 Assistent zur Erzeugung einer JUnit-Testklasse in Eclipse
5 Selenium Core mit der TestSuite "TestSuite.html"
6 Testergebnisse der Testsuite "TestSuite.html" im TestRunner
7 Übersicht über die Verwendung von Selenium RC im Driven Mode
8 Selenium Grid steuert das gleichzeitige Ausführen von Tests auf mehreren Remote Control Servern
9 Selenium Grib Hub Konsole
10 Selenium IDE
11 Konfigurationsoberfläche Hudson
12 Übersicht über die Projekte
13 Build Verlauf
14 Trend der Testergebnisse
15 Zusammenspiel Hudson, Selenium und Junit

8 Tabellenverzeichnis

Tab.-Nr. Beschreibung
1 Einsatzzweck / Software
2 Übersicht über die Action-Kommandos

9 Fußnoten

  1. URL:http://www.neogrid.de/pc_lexikon.php?Feld=build&submit=suchen
  2. Vgl. Stahlknecht/Hasenkamp (1997), Seite 313
  3. URL:http://www.neogrid.de/pc_lexikon.php?Feld=framework&submit=suchen
  4. Vgl. Li/Wu (2004), Seite 4
  5. Vgl. Sun (o.D.), o.S.
  6. Vgl. Hoffmann (2008), Seite 6
  7. URL:http://www.neogrid.de/pc_lexikon.php?Feld=build&submit=suchen
  8. Vgl. Holmes (2003), Seite 5 ff.
  9. Vgl. Stahlknecht/Hasenkamp (1997), Seite 313
  10. Vgl. Frühauf/Ludewig/Sandmayr (2007), Seite 29
  11. Vgl. Spillner (2005), Seite 1
  12. Vgl. Liggesmeyer (2009), Seite 2
  13. Vgl. Spillner (2005), Seite xvii
  14. Vgl. Liggesmeyer (2009), Seite 4
  15. Vgl. Meszaros (2007), Seite 39 ff.
  16. Vgl. Meszaros (2007), Seite 298
  17. Vgl. Link (2007), Seite 29 ff.
  18. Vgl. Spillner (2005), Seite 42 ff.
  19. Vgl. Spillner (2005), Seite 53 und 54
  20. Vgl. Meszaros (2007), Seite 6
  21. Vgl. Spillner (2005), Seite 209
  22. Vgl. Link (2005), Seite 21
  23. Vgl. Link (2005), Seite 24 und 25
  24. Vgl. Link (2005), Seite 25
  25. Vgl. Link (2005), Seite 30
  26. Vgl. Hatcher (2002), Seite 88 ff.
  27. Vgl. Link (2005), Seite 90
  28. Vgl. Link (2005), Seite 26 ff.
  29. Vgl. Link (2005), Seite 29 ff.
  30. Vgl. Meszaros (2007), Seite 6
  31. Vgl. Imrie (2009) Seite 1
  32. Vgl. Kain (2008), Seite 11 und 12
  33. Vgl. May-Pumphrey/Newhook (2009), Seite 6
  34. Vgl. Kain (2008), Seite 13
  35. Vgl. Kain (2008), Seite 101
  36. URL: https://developer.mozilla.org/En/Same_origin_policy_for_JavaScript
  37. URL:http://www.mozilla-europe.org/de/firefox/
  38. Vgl. Kain (2008), Seite 41
  39. Vgl. Kain (2008), Seite 14
  40. Vgl. May-Pumphrey/Newhook (2009), Seite 6 und 7
  41. URL:https://developer.mozilla.org/en/XUL_Tutorial/The_Chrome_URL
  42. Vgl. Kain (2008), Seite 113 ff.
  43. Vgl. Kain (2008), Seite 113 ff.
  44. Vgl. Kain (2008), Seite 139 ff.
  45. Vgl. Selenium (o.D.), o.S.
  46. Vgl. Kain (2008), Seite 123
  47. Vgl. Kain (2008), Seite 45 ff.
  48. Vgl. Kain (2008), Seite 49 und 50
  49. Vgl. Kain (2008), Seite 64
  50. Vgl. Kain (2008), Seite 64 ff.
  51. Vgl. Kain (2008), Seite 75
  52. Vgl. Kain (2008), Seite 75
  53. Vgl. Kain (2008), Seite 81 ff.
  54. URL:http://seleniumhq.org/docs/04_selenese_commands.html
  55. URL:http://www.w3.org/DOM/
  56. URL:http://www.w3.org/TR/xpath
  57. URL:http://seleniumhq.org/docs/04_selenese_commands.html
  58. URL:http://www.w3.org/TR/css3-selectors/
  59. URL:http://seleniumhq.org/docs/04_selenese_commands.html
  60. Vgl. Sun (2009), Seite 4
  61. Vgl. Sun (2009), Seite 3
  62. URL:http://wiki.hudson-ci.org/display/HUDSON/Plugins
  63. Vgl. Sun (2009), Seite 5 ff.
  64. Vgl. Fowler (2006), o.S.

10 Literatur- und Quellenverzeichnis

DbUnit (o.D.)DbUnit (Hrsg.): About DbUnit, o.D., http://www.dbunit.org/ (09.01.2010 18:09)
Flowers (2008) Flowers, Jay: Neudefinition Ihres Buildprozesses mit kontinuierlicher Integration, März 2008, http://msdn.microsoft.com/de-de/magazine/cc337886.aspx (29.12.2009 15:51)
Fowler (2006) Fowler, Martin: "Continuos Integration", Mai 2006,

http://martinfowler.com/articles/continuousIntegration.html (02.01.2010 15:40)

Frühauf/Ludewig/Sandmayr (2007) Frühauf, Karol; Ludewig, Jochen; Sandmayr, Helmut: Software-Prüfung: Eine Anleitung zum Test und zur Inspektion, Vdf Hochschulverlag, 6. überarbeitete und aktualisierte Auflage 2007, Zürich, 2007
Hatcher (2002) Hatcher, Erik; Loughran, Steve: Java Development with Ant, Manning Publications, 2. Auflage, 2002
Hoffmann (2008) Hoffmann, Dirk: Software-Qualität, Springer Verlag, 1. Auflage, Berlin, 2008
Hommes (2003) Hommes, Werner: Werkzeuge zur Testautomatisierung, GRIN Verlag, 1. Auflage, München, 2003
Imrie (2009) Imrie, Alexandra: Automatisiertes GUI-Testen von RCP-Anwendungen, April 2009, http://it-republik.de/jaxenter/artikel/Automatisiertes-GUI-Testen-von-RCP-Anwendungen-2227.html (9.11.2009 15:03)
JUnit (o.D.)JUnit.org (Hrsg.): JUnit.org - Ressources for Test Driven Development, o.D., http://www.junit.org/ (09.01.2010 18:09)
Kain (2008) Kain, Michael: Selenium. Web-Applikationen automatisiert testen, Open Source Press, 1. Auflage, München, 2008
Li/Wu (2004) Li, Kanglin; Wu, Mengqi: Effective GUI Test Automation, John Wiley & Sons, 1. Auflage, 2004
Liggesmeyer (2009) Liggesmeyer, Peter: Software-Qualität: Testen, analysieren und verifizieren von Software, Spektrum Akademischer Verlag, 2. Auflage, Heidelberg, 2009
Link (2005) Link, Johannes: Softwaretests mit JUnit, dpunkt.verlag, 2. Auflage, Heidelberg, 2005
May-Pumphrey/Newhook (2009)May-Pumphrey, Mary Ann; Newhook, Peter: Selenium Documentation Release 1.0 Selenium Project, 2009, http://seleniumhq.org/docs/book/Selenium_Documentation.pdf (15.10.2009 12:18)
Meszaros (2007)Meszaros, G.: XUnit Test Patterns, Refactoring Test Code, Addison-Wesley Longman, 3. Auflage, Amsterdam, 2007
Selenium (o.D.)SeleniumHQ (Hrsg.): Selenium-RC, o.D., http://seleniumhq.org/docs/05_selenium_rc.html (11.01.2010 20:05)
Spillner (2005)Spillner, A., Linz, T.: Basiswissen Softwaretest, dpunkt.Verlag, 3. überarbeitete und aktualisierte Auflage 2005, Korrigierter Nachdruck 2007, Heidelberg, 2005
Stahlknecht/Hasenkamp (1997) Stahlknecht, Peter; Hasenkamp, Ulrich: Einführung in die Wirtschaftsinformatik, Springer, 8. Auflage, Berlin, 1997
Sun (2009) Sun Microsystems (Hrsg.): Developing Software, Collaboratively with Hudson, White Paper, 2009, https://www.sun.com/offers/details/hudson.xml (29.12.2009 15:33)
Sun (o.D.) Sun Microsystems (Hrsg.): Trail: The Reflection API, o.D., http://java.sun.com/docs/books/tutorial/reflect/ (10.01.2010 19:58)
Persönliche Werkzeuge