X - Department of Information Systems

Werbung
Westfälische Wilhelms-Universität Münster
Ausarbeitung
Qualitätssicherung von Software mit Testwerkzeugen
im Rahmen des Seminars „Qualitätsmanagement in der Softwaretechnik“
Elke Schmitt
Themensteller: Prof. Dr. Herbert Kuchen
Betreuer: Roger Müller
Institut für Wirtschaftsinformatik
Praktische Informatik in der Wirtschaft
Inhaltsverzeichnis
1
Was bringt Werkzeug-Unterstützung beim Testen von Software? ........................... 1
2
Klassifikation von Testwerkzeugen........................................................................... 2
3
Rational Testwerkzeuge............................................................................................. 4
4
3.1
Übersicht über die Programmpakete................................................................. 4
3.2
Die Rational Team Unifying Platform.............................................................. 4
3.3
Rational Functional Tester for Java and Web................................................... 6
3.4
Rational PurifyPlus ........................................................................................... 7
Parasoft Jtest ............................................................................................................ 10
4.1
Übersicht über die Funktionen und Integrationsmöglichkeiten...................... 10
4.2
Unit-Tests mit JTest........................................................................................ 11
4.2.1
4.2.2
4.2.3
5
Blackbox-Test............................................................................................. 12
Whitebox-Test ............................................................................................ 14
Regressions-Test......................................................................................... 15
Bewertung der Werkzeuge ...................................................................................... 16
Anhang A........................................................................................................................ 18
Anhang B ........................................................................................................................ 19
Anhang C ........................................................................................................................ 20
Anhang D........................................................................................................................ 21
Literaturverzeichnis ........................................................................................................ 23
II
Kapitel 1: Was bringt Werkzeug-Unterstützung beim Testen von Software?
1 Was bringt Werkzeug-Unterstützung beim Testen von
Software?
Die erste Frage, die zum Thema Werkzeug-Unterstützung beim Testen von Software
gestellt werden muss, ist: Warum sollte man Tests softwaregestützt durchführen? Es
gibt schließlich die Möglichkeit, jedes Testproblem manuell anzugehen, ohne die
Unterstützung durch Software. Dieses manuelle Vorgehen erspart dem Team die
Anschaffung teurer Software und die Einarbeitung in die neuen Programme und
Techniken.
Das Argument für die Automatisierung von Softwaretest ist einfach. Beizer [Be95] sagt
zu dieser Frage: „The argument to use is simple: Manual Testing doesn’t work. “. Die
Gründe hierfür sind vielfältig und liegen einerseits in der großen Komplexität von
Programmen und den entsprechend komplexen Tests, andererseits in der Ineffizienz und
Unzuverlässigkeit von manuellem Testen aufgrund nicht möglicher Wiederverwendung
der einmal durchgeführten Tests. Jede Wiederholung eines manuellen Tests führt zu
neuen Fehlerquellen, da Menschen jedes Mal andere Fehler bei der Durchführung von
Tests machen können. Besonders häufige Wiederholungen derselben Tests führen zu
Langeweile und Konzentrationsverlust, was den Effekt noch verstärkt.
Da Softwareentwicklung ein iterativer Prozess ist, können die einmal mit Software
entwickelten Tests wiederholt angewendet werden; das erspart viel Arbeit und sorgt für
eine höhere Abdeckung des neuen Programms durch Tests. Bei jeder Veränderung am
Programmcode kann auf die vorhandenen Testfälle zurückgegriffen werden, um neu
entstandene Probleme aufzudecken oder die Korrektheit des Programms zu bestätigen.
Ein weiterer entscheidender Grund für die werkzeuggestützte Durchführung von Tests
ist die Belegbarkeit der Ergebnisse. Über die Protokolldateien und generierten Berichte
kann der Kunde oder eine interne Controlling-Instanz über die korrekte Ausführung der
Tests informiert werden.
Ein Vergleich der Kosten zwischen manuellen und automatisierten Tests kann nur
schwer vorgenommen werden. Manuelles Testen kostet in jedem Projekt und jedem
Entwicklungsschritt erneut Geld und Zeit. Viele Kosten entstehen beim manuellen
Testen erst in späteren Stadien der Softwareentwicklung, z. B. in der Testphase beim
Kunden,
sind
jedoch
auf
die
mangelnde
Zuverlässigkeit
der
Testmethode
1
Kapitel 2: Klassifikation von Testwerkzeugen
zurückzuführen. Die Kosten der automatisierten Tests sind zu Beginn höher, da
Programme und Hardware angeschafft und die Test-Teams geschult werden müssen.
Diese Kosten fallen jedoch nur einmal für viele Projekte an, außerdem verhindern die
Investitionen weitere Kosten in den späteren Phasen der Entwicklung.
In dieser Ausarbeitung werden Werkzeuge zur Unterstützung und Durchführung von
Tests der Firmen Rational (Teil von IBM) und Parasoft vorgestellt und verglichen.
Hierzu wird in Kapitel 2 zunächst ein Vorschlag zur Einteilung der Testwerkzeuge nach
ihren Funktionen gemacht und die in Kapitel 3 und 4 vorgestellten Werkzeuge in dieses
Schema eingeordnet. Kapitel 3 gibt eine Übersicht über die Produktpalette von Rational
im Bereich der Testwerkzeuge und stellt einige der Programme anhand von Beispielen
vor. Das Produkt von Parasoft, JTest, wird in Kapitel 4 ebenso anhand von Beispielen
vorgestellt. In Kapitel 5 folgen der Vergleich der Werkzeuge der beiden Firmen und ein
Vorschlag für die Verwendung in der Softwareentwicklung.
2 Klassifikation von Testwerkzeugen
Je nach Testart gibt es verschiedene Werkzeuge, welche die Arbeit unterstützen können.
In [Li02] wird eine Gliederung nach Typen der Testwerkzeuge vorgeschlagen:
•
Dynamische Testwerkzeuge
o Strukturorientierte Testwerkzeuge
o Funktionsorientierte Testwerkzeuge
o Regressionswerkzeuge
o Leistungs- und Stresstestwerkzeuge
•
Statische Testwerkzeuge
o Messwerkzeuge
o Stil-Analysatoren
o Werkzeuge zur Erzeugung von Grafiken und Tabellen
o Slicing-Werkzeuge
o Datenflussanomalieanalyse-Werkzeuge
2
Kapitel 2: Klassifikation von Testwerkzeugen
•
Formale Verifikationswerkzeuge
•
Modellierende und analysierende Werkzeuge
Die am Markt erhältlichen Programme und Programmpakete decken häufig mehrere
Bereiche ab und kombinieren die Ergebnisse zu einer umfassenden Ergebnishistorie.
Die in dieser Arbeit vorgestellten Werkzeuge ordnen sich wie in Tab. 2.1 dargestellt in
die Gliederung ein. In der Tabelle wurden die beiden letzten Punkte der Aufzählung
weggelassen,
da
sie
nicht
von
den
Programmen
abgedeckt
werden.
Neu
hinzugekommen ist die Gruppe der Werkzeuge zur Organisation und Planung von Tests
im Team.
Rational
Team
Unifying
Platform
Functional
Tester for
Java and
Web
Dynamische
Testwerkzeuge
Strukturorientierte
Testwerkzeuge
Purify Plus
JTest
X
X
Funktionsorientierte
Testwerkzeuge
X
X
Regressionswerkzeuge
X
X
Leistungs- und
Stresstestwerkzeuge
Statische Testwerkzeuge
Parasoft
X
Messwerkzeuge
X
Stil-Analysatoren
X
Werkzeuge zur Erzeugung von
Grafiken und Tabellen
X
Slicing-Werkzeuge
X
DatenflussanomalieanalyseWerkzeuge
Werkzeuge zur Planung und
Organisation der Zusammenarbeit
im Team
X
Tab. 2.1 Funktionsübersicht der Testwerkzeuge
Die genaue Erklärung der einzelnen Funktionen erfolgt in den Kapiteln zu den
Testwerkzeugen, die Programme wurden hier nur nach ihren Hauptfunktionen
eingegliedert.
3
Kapitel 3: Rational Testwerkzeuge
3 Rational Testwerkzeuge
3.1 Übersicht über die Programmpakete
Rational bietet eine große Anzahl an Produkten zum Testen von Software an. Die
Produkte werden in verschiedenen Paketen angeboten und arbeiten teilweise ineinander
greifend. Rational teilt die Produkte in zwei Gruppen ein, die Rational System Testing
Family sowie das Developer Testing [Ra04].
Die Rational System Testing Family besteht aus verschiedenen Modulen, die über den
Rational TestManager gesteuert und integriert werden. Das zentrale Produktpaket stellt
die Rational Team Unifying Platform dar. Es enthält neben dem TestManager zur
Kontrolle und Steuerung von manuellen und automatisierten Tests sechs weitere
Module: Unified Process, RequisitePro, ClearCase LT, ClearQuest, ProjectConsole und
SoDA. Wahlweise können zusätzlich die selbständigen Module und Pakete Rational
Robot, Rational Functional Tester for Java and Web und Rational Performance Tester
erworben und integriert werden.
Der Bereich Developer Testing beinhaltet die Entwicklungsumgebung IBM Rational
Rose XDE Developer Plus, in der bereits einige Testfunktionen integriert sind. Rational
Testing RealTime ist für Laufzeittests von plattformübergreifenden und eingebetteten
Systemen geeignet. Ebenfalls verschiedene Laufzeittests bietet Rational PurifyPlus,
wobei das Angebot an Tests größer ist als bei RealTime, dafür aber auf bestimmte
Programmiersprachen und Plattformen beschränkt.
Im folgenden Abschnitt werden einige Module vorgestellt und teilweise anhand eines
Beispiels näher erläutert.
3.2 Die Rational Team Unifying Platform
Das Programmpaket Rational Team Unifying Platform besteht aus einer Reihe von
Werkzeugen, die auf die Organisation des Programmentwicklungs- und Testprozesses
abzielen und neben der Zusammenarbeit untereinander auch mit verschiedenen weiteren
Werkzeugen von Rational integrieren.
4
Kapitel 3: Rational Testwerkzeuge
Abb. 3.1 Module der Rational Team Unifying Platform
Das Konzept der Software-Entwicklung mit Produkten von Rational basiert auf dem
Rational Unified Process, einem Vorgehensmodell, das laut Rational momentan zu
einem de facto Industriestandard wird. Das gleichnamige Modul der Team Unifying
Platform bietet eine Wissensbasis, die Softwareentwickler und Tester durch den
Entwicklungsprozess führt.
Rational RequisitePro ermöglicht die Verwaltung von Anforderungen. Es basiert auf
Word-Dokumenten, die mit einer Anforderungsdatenbank verknüpft sind und stellt die
Daten auch anderen Modulen der Rational System Testing Family zur Verfügung.
Für das Change-Management und die Verfolgung von Fehlern bietet Rational
ClearQuest eine flexible Grundlage. Es bietet individuell gestaltbare Formulare zur
Meldung von Fehlern und Change-Requests, die den jeweiligen Entwicklern so
regelmäßig und einheitlich gemeldet werden.
Rational ClearQuest arbeitet eng mit dem Versionskontrollwerkzeug Rational
ClearCase LT zusammen. Dieses verwaltet für die verschiedenen Dokumente und
Programmteile wie Dokumentation, Modelle und Testläufe die Versionsnummern und
verknüpft diese mit den Fehlermeldungen und Change-Requests aus ClearQuest.
Als Schnittstelle zu Management und Kunden dient die Rational ProjectConsole. Sie
generiert aus den Modulen der Rational Suite sowie aus Programmen von anderen
Anbietern Berichte, die den Projektstatus zusammengefasst darstellen. Die Darstellung
erfolgt als Website. Um die Informationen nutzen zu können, muss entweder eine
5
Kapitel 3: Rational Testwerkzeuge
Lizenz der ProjectConsole oder eine einzeln erhältliche ProjectConsole Client Lizenz
vorhanden sein.
Das Kernstück aller Aktivitäten des Testens bildet der Rational TestManager. Er ist
nicht nur Bestandteil der Team Unifying Platform, sondern wird auch bei den drei
anderen Modulen der System Testing Family mitgeliefert. Mit diesem Tool werden
manuelle Tests, Funktionstests, Regressionstests, Performancetests und Laufzeittests
überwacht und gesteuert. Gefundene Fehler können an ClearQuest gemeldet und in
Reporten zusammengefasst werden.
Zur Dokumentation dient das Modul Rational SoDA, das die Erzeugung und Verteilung
von verschiedenen Arten der Projektdokumentation unterstützt.
3.3 Rational Functional Tester for Java and Web
Abb. 3.2 Module des Rational Functional Tester for Java and Web
Der Functional Tester for Java and Web ist ein Programmpaket aus dem TestManager,
der im Abschnitt 3.2 kurz vorgestellt wurde, und dem XDE Tester, der in früheren
Versionen RobotJ hieß. Getestet werden können Programme der Techniken J2EE, J2SE,
HTML, DHTML, XML, JavaScript und Java Applets. Die Funktionstests lassen sich
für Regressionstests wieder verwenden. Diese Wiederverwendung wird durch die
Technik ScriptAssure™ vereinfacht, welche Komponenten von Programmen,
beispielsweise Buttons, auch nach Umbenennung wieder erkennt. Der XDE Tester kann
in den XDE Developer oder WebSphere integriert werden und bringt eine eigene
Eclipse Version als Oberfläche mit.
Die Erzeugung von Test erfolgt mittels einer Java-API, die ähnlich der API von JUnit
aufgebaut ist und den Ablauf von Tests in Java-Klassen festhält. Diese Klassen können
entweder von Hand geschrieben werden oder mittels eines Rekorders automatisch
erzeugt werden. Getestet wird zur Laufzeit, eine Analyse des Codes erfolgt nicht.
Ein einfaches Beispiel für eine Testklasse ist im Folgenden dargestellt:
6
Kapitel 3: Rational Testwerkzeuge
import
import
import
import
import
import
resources.ButtonTestHelper;
com.rational.test.ft.*;
com.rational.test.ft.object.interfaces.*;
com.rational.test.ft.script.*;
com.rational.test.ft.value.*;
com.rational.test.ft.vp.*;
/**
* @author Elke Schmitt
*/
public class ButtonTest extends ButtonTestHelper
{
/**
* Script Name
: <b>ButtonTest</b>
* Generated
: <b>31.03.2004 15:17:29</b>
* Description
: XDE Tester Script
* Original Host : WinNT Version 5.1 (Service Pack 1)
*
* @since 2004/03/31
* @author Elke Schmitt
*/
public void testMain (Object[] args)
{
startApp("DisplayMessage"); //zu testendes Programm aufrufen
// Frame: Message
Yes().click();
No().click();
Yes().click();
Message().close();
//Button betätigen
//Button betätigen
//Button betätigen
//Programm schließen
}
}
Das getestete Programm findet sich in Anhang B, es besteht aus einem Fenster sowie
zwei Buttons mit den Titeln „Yes“ und „No“, die beim Anklicken eine Ausgabe im
Konsolenfenster erzeugen. Die Testklasse startet das Programm, führt drei Mausklicks
aus und schließt das Programm wieder. Sie wurde mit dem Rekorder erzeugt.
3.4 Rational PurifyPlus
7
Kapitel 3: Rational Testwerkzeuge
Abb. 3.3 Module von Rational PurifyPlus
Rational PurifyPlus ist ein Programmpaket, das drei Komponenten enthält:
•
PureCoverage überwacht die genutzten und damit getesteten Teile des
Programmcodes und arbeitet mit Purify und Quantify zusammen.
•
Purify überwacht für C, C++ und Java den Speicherverbrauch für alle Methoden
und hilft bei der Entdeckung von Memory Leaks.
•
Quantify bietet Möglichkeiten zur Identifikation von Bottlenecks in der
Performance von C, C++ und Java Programmen. Es überwacht die ausgeführten
Programme und berichtet die Lauf- und Wartezeiten der einzelnen Threads
sowie deren Ursachen, wie z. B. das Warten auf Benutzereingaben, Freigabe von
Objekten und vom Programmcode geforderte Pausen.
Als Beispiel für die Vorgehensweise der Programme dient das kurze Java-Programm
aus Anhang A.
Zunächst wird das Programm in PureCoverage aufgerufen, um die Vollständigkeit der
durchgeführten Tests zu überprüfen. Das Beispielprogramm in der vorliegenden Form
durchläuft nur 85,71% des Codes, die Methode „print“ wird nicht aufgerufen und damit
in den folgenden Tests auch nicht berücksichtigt. Für einen vollständigen Test müsste
also die Main-Methode um den Aufruf der Methode „print“ erweitert werden, um jede
Zeile des Codes zumindest einmal zu durchlaufen.
Abb. 3.4 PureCoverage – Übersicht der Methoden
8
Kapitel 3: Rational Testwerkzeuge
Um die nicht ausgeführten Teile des Codes zu finden, bietet PureCoverage die Ansicht
des Programmcodes, ausgeführte Teile werden blau dargestellt, übersprungene Teile
rot.
Der nächste Schritt ist der Aufruf in Purify. Da unter Java die Speicherallokation
automatisch geschieht, werden keine Zugriffsfehler auf den Speicher festgestellt. Häufig
unterschätzt werden Memory Leaks in Java, die auf zwei Arten entstehen können.
Durch Objektreferenzen, die nicht länger benötigt werden, kann der Garbage Collector
die zugewiesenen Speicherbereiche nicht freigeben. Dies kann z. B. passieren, wenn
Objekte in Arrays referenziert, und diese Arrays dann vergessen werden. Ein Memory
Leak kann auch entstehen, wenn ein Javaprogramm Speicher außerhalb der Java
Instanzen nutzt. Dies passiert z. B. bei der Nutzung des AWT, wo Fensterdarstellungen
im Systemspeicher abgelegt werden.
Purify unterstützt die Minimierung solcher Memory Leaks durch die Möglichkeit,
Schnappschüsse während der Programmausführung zu machen und zu vergleichen. So
können die Methoden identifiziert werden, die für die Verschwendung von
Speicherplatz verantwortlich sind. Ausführliche Informationen zu diesem Thema finden
sich in [Ra02] auf den Seiten 26 ff.
In Abb. 3.5 ist die Speicherzuweisung eines Schnappschusses abgebildet.
Abb. 3.5 Purify Übersicht der Methoden
Für jede Methode kann ein ausführlicher Bericht angezeigt werden, der neben anderen
Informationen die einzelnen Objekte und ihren Speicherverbrauch enthält.
9
Kapitel 4: Parasoft Jtest
Zur Aufdeckung von Performance Bottlenecks wird das Programm schließlich in
Quantify gestartet. Der Bericht zeigt für jede Methode die verbrauchte Zeit und für
jeden Thread die Lauf- und Wartezeiten mit dem Grund für die Wartezeit. Mit Hilfe
dieser Informationen kann der Programmierer die Schwachstellen identifizieren und
wenn möglich beheben. Neben den Auslösern für lange Programmlaufzeiten lassen sich
durch Wiederholung dieser Tests auch diejenigen Faktoren bestimmen, die für starke
Schwankungen der Laufzeit sorgen, beispielsweise bei zufälliger Reihenfolge von
Threads, die sich im schlechtesten Fall gegenseitig blockieren und im günstigsten Fall
genau nacheinander Systemressourcen beanspruchen. Diese Zufälligkeit kann dann
behoben werden um die Laufzeit des Programms zu stabilisieren und zu verkürzen.
Abb. 3.6 Quantify - Übersicht der Threads
4 Parasoft Jtest
4.1 Übersicht über die Funktionen und Integrationsmöglichkeiten
Anders als bei dem Produktspektrum von Rational gibt es von Parasoft für die
Durchführung von Tests ein Programm, das neben Unit-Tests in den Typen Blackbox-,
Whitebox- und Regressionstests auch die Einhaltung von Coding Standards unterstützt.
Jtest läuft sowohl unabhängig von weiterer Software, als auch integriert in gängige
Entwicklungsumgebungen wie Eclipse, JBuilder und SunForte.
10
Kapitel 4: Parasoft Jtest
Abb. 4.1 Oberfläche von JTest
JTest ermöglicht neben Standard-Javacode auch das Testen von Java Servlet Pages
(JSP). Zu diesem Zweck werden benötigte Test-Stubs automatisch generiert. Auch für
Klassen, die Benutzereingaben erwarten, generiert JTest entsprechende Stubs, die
Eingaben erzeugen.
Aus den Testergebnissen erstellt JTest automatisiert Berichte im HTML-Format. Die
Erstellung eigener Berichtstypen unterstützt JTest durch die Erzeugung einer XMLDatei mit den Testergebnissen, deren Inhalt mit XSL oder ähnlichen Techniken in
eigene Dokumente integriert werden kann.
4.2 Unit-Tests mit JTest
Bei Unit-Tests wird die kleinste mögliche Einheit des Programms getestet, im Falle von
Java also die Klasse, sobald sie kompiliert wurde. So wird es den Programmierern
ermöglicht, so früh wie möglich Fehler zu finden und zu eliminieren. Dies spart beim
späteren Testen viel Arbeit und aufwändige Fehlersuche, da die Quellen der Fehler zum
Zeitpunkt der Unit-Tests noch eng einzugrenzen sind. JTest unterstützt Unit-Tests auf
verschiedene Arten, die in den folgenden Unterkapiteln vorgestellt werden. Näheres zu
Unit-Tests findet sich in [Pa02].
11
Kapitel 4: Parasoft Jtest
4.2.1 Blackbox-Test
Es gibt vier Möglichkeiten, Blackbox-Tests für JTest zu erzeugen. Die erste
Möglichkeit nutzt des Parasoft Produkt „Design by Contract“. Es dient der Festlegung
von Zuständen, die vor oder nach Ausführung eines Programmteiles (pre oder post
conditions) gelten, solchen die jederzeit während der Ausführung einer Methode gelten
(assertions), sowie von Zuständen, die immer zutreffen, wenn eine Methode aufgerufen
werden kann (invariants). Wenn Programmcode mit „Design by Contract“ erzeugt oder
bearbeitet wurde, enthält er die entsprechenden Zustände in einem standardisierten
Kommentarformat, ähnlich der Technik von Javadoc. Aus diesen Kommentaren kann
JTest Blackbox-Tests erzeugen, die die Einhaltung der Zusicherungen überwachen.
Weitere Möglichkeiten zur Erzeugung von Tests bestehen im Schreiben eigener
Testklassen oder dem Verwenden von JUnit-Testklassen. Für statische Methoden und
Instanz Methoden können einfache Eingabewerte auch direkt eingetragen werden, die
Tests werden dann automatisch erzeugt. Da „Design by Contract“ nicht Bestandteil
dieser Arbeit ist, werden im Folgenden lediglich die drei anderen Möglichkeiten
vorgestellt. Ausführliche Informationen zu der Technik „Design by Contract“, die in der
gleichnamigen Software genutzt wird, findet sich auf der Homepage der
Programmiersprache Eiffel [DbC04].
Abb. 4.2 Blackbox Test mit JUnit
JTest unterstützt den Tester bei der Erzeugung von JUnit-kompatiblen Testklassen,
indem es das Gerüst für die Klassen automatisch generiert. Die Methoden müssen dann
nur noch mit dem Testablauf gefüllt werden. Der folgende Code-Ausschnitt zeigt einen
Test der Klasse Simple (siehe Anhang C), die vollständige Testklasse ist in Anhang D
aufgeführt.
public class SimpleTest extends TestCase{
/**
* Constructs a test case for the test specified in the name
argument.
*/
public SimpleTest (String name)
{
12
Kapitel 4: Parasoft Jtest
super (name);
/*
* This constructor should not be modified. Any initialization
* code should be placed in the setUp() method instead.
*/
}
/**
* Test for constructor: 'Simple ()'
*/
public void testSimple ()
{
/* Replace the default fail statement with your test code. */
fail ("Empty test case.");
}
/**
* Test for method: 'static boolean startsWith (String, String)'
*/
public void testStartsWith ()
{
/* Replace the default fail statement with your test code. */
fail ("Empty test case.");
}
//[…]
die vollständige Klasse findet sich in Anhang D
/**
* Test for method: 'static int add (int, int)'
*/
public void testAdd ()
{
int result = 0;
result = Simple.add (5, 88);
assertTrue ("The result should be 93", result == 93);
}
//[…]
die vollständige Klasse findet sich in Anhang D
}
Die Methode testStartsWith zeigt, wie JTest die Testmethoden erzeugt. Die Methode
fail(„Empty Test Case“) wird beim Aufruf der Testklasse automatisch einen Fehlschlag
erzeugen, deren Nachricht „Empty Test Case“ den Tester auf den fehlenden Inhalt der
Testmethode aufmerksam macht (siehe Abb. 4.2.). Die Methode testAdd() zeigt einen
einfachen Test, der bei korrekter Funktion der Methode add() aus der zu testenden
Klasse erfolgreich durchgeführt wird. Der Inhalt der Methode testAdd() ist in diesem
Beispiel der einzige nicht von JTest automatisch erzeugte Code.
Wenn die Testklassen bereits in JUnit-Format vorhanden sind, kann JTest diese auch
importieren.
Statischen Methoden können auch ohne Erzeugung von Test-Klassen Eingabewerte
zugewiesen werden. Der Rückgabewert muss dann beim ersten Durchlauf als korrekt
13
Kapitel 4: Parasoft Jtest
markiert werden, damit bei folgenden Tests das Ergebnis automatisch überprüft werden
kann.
Abb. 4.3 Direkte Zuweisung eines Eingabewertes beim Blackbox-Testen
Abb. 4.5 zeigt das Ergebnis der direkten Zuweisung des Wertes 7 (ARG1 = 7) an die
Methode returnStaticInt(), der Rückgabewert (ebenfalls 7) wurde als korrekt markiert.
Auf die Wiedergabe der getesteten Klasse StaticInstanceExample wurde aufgrund ihrer
Einfachheit verzichtet.
4.2.2 Whitebox-Test
Die Whitebox-Tests von Jtest finden nicht abgefangene Runtime Exceptions. Jtest
findet eine Runtime Exception bei der dynamischen Analyse der Class-Datei
simple.class, deren Sourcecode sich in Anhang C befindet. Wie in Abb. 4.4 zu sehen,
gibt Jtest die Art der Exception (StringIndexOutofBoundsException) sowie die
Aufrufparameter des Testlaufes an. Der Benutzer kann sich jetzt den Sourcecode der
Klasse ansehen und editieren, um den Fehler zu beheben. Er kann auch den Testlauf
anzeigen lassen, der die Exception ausgelöst hat.
Abb. 4.4 Whitebox-Test mit JTest
Neben dem dynamischen Testen bietet Jtest auch statische Analysen des Codes im
Hinblick auf Fehler und Nichteinhaltung von Coding Standards.
14
Kapitel 4: Parasoft Jtest
Abb. 4.5 Statische Analyse mit JTest
In Abb. 4.5 sind eine Reihe von Fehlern im Code der Datei simple.java (Sourcecode
siehe Anhang C) aufgelistet. In Zeile 8 enthält der Code einen Tippfehler, so dass
innerhalb der Fallunterscheidung ein Textlabel auftritt (case10 statt case 10). Jtest
macht auf fehlende Konstruktoren, Javadoc-Kommentare und Dateiheader aufmerksam
und weist auf die Verwendung von Konstanten hin, die nicht als Konstante, sondern als
Zahl codiert wurden.
Da Coding Standards für jedes Team und für jedes Projekt anders sind, werden die
jeweils gültigen Standards in einer Properties Datei abgelegt und können so im
gesamten Team verwendet werden. JTest liefert eine große Anzahl von bestehenden
Standards mit, welche durch eigene Standards ergänzt werden können.
4.2.3 Regressions-Test
Einmal durchgeführte Tests in JTest werden gespeichert und können nach
Veränderungen am Code für jede Klasse erneut durchgeführt werden. Dies stellt sicher,
dass die durchgeführten Veränderungen keine bereits korrekt arbeitenden Klassen
beschädigt haben. JTest merkt sich nicht nur die als korrekt markierten Ergebnisse und
nutzt sie als Referenz, sondern vergleicht automatisch die Ergebnisse vorhergehender
Durchläufe und meldet jede Abweichung.
15
Kapitel 5: Bewertung der Werkzeuge
Abb. 4.6 Regressionstest in JTest
In Abb. 4.6 ist ein Regressionstest dargestellt, bei dem im ersten Durchlauf des
automatischen Tests der Methode add() andere Rückgabewerte auftraten als beim
zweiten Durchlauf (Zeilen 2 und 3). Ebenfalls verändert hat sich der manuell erzeugte
Test der Methode, das als korrekt markierte Ergebnis wurde nicht erneut ausgegeben
(Zeile 8). Die Veränderungen wurden durch Manipulation der Klasse Simple erreicht,
deren Methode add() im zweiten Durchlauf nicht nur die beiden Eingabewerte, sondern
zusätzlich den Wert auf 3 den Rückgabewert addierte.
5 Bewertung der Werkzeuge
Die Produkte von Rational und JTest erfüllen im Testbetrieb verschiedene Aufgaben,
ein direkter Vergleich ist nicht möglich. Es wird daher im Folgenden auf die Eignung
der Programme in ihren jeweiligen Aufgabenbereichen eingegangen, die Kapitel 2
entnommen werden können.
Bei JTest ist insbesondere ein Vergleich mit dem Open Source Produkt JUnit [Ju04]
nötig, der die Argumente für das kommerzielle Werkzeug für Unit-Tests liefern muss.
Das Produktspektrum von Rational zeichnet sich durch hohe Modularität aus, so dass je
nach Größe und Art des Projektes nur die erforderlichen Programme gekauft werden
müssen. Bei der Zusammenarbeit mit gängigen Entwicklungsumgebungen sind sowohl
bei Rational als auch bei Parasoft die verbreiteten Umgebungen berücksichtigt. Den
Bereich der statischen Analyse decken die Produkte von Rational nicht ab, er ist
allerdings bereits in vielen Entwicklerumgebungen integriert. In den einzelnen
Bereichen machen die Werkzeuge einen guten Eindruck, die Bedienung ist leicht zu
erlernen, wenn die nötige Theorie hinter den Tests verstanden wurde. Der erfahrene
Programmierer
erhält
vielfältige
Unterstützung
bei
der
Verbesserung
der
Softwarequalität. Für Programmiereinsteiger ist die Produktpalette von Rational kaum
geeignet, dass die Fehlerbereinigung gute Kenntnisse der Technik voraussetzt.
16
Kapitel 5: Bewertung der Werkzeuge
JTest ist nicht modular aufgebaut und arbeitet lediglich mit dem Parasoft Produkt
„Design by Contract“ zusammen. Es enthält Funktionen für statische und dynamische
Tests, letztere auch ohne Zugriff auf den Source Code. JTest bietet zusätzlich zum
Funktionsumfang von JUnit zahlreiche Automatisierungsmöglichkeiten, es generiert
einen großen Teil der offensichtlich durchzuführenden Tests ohne Benutzereingriff.
Dies ermöglicht ein kontinuierliches Testen ohne großen Zeitaufwand während der
Entwicklung. Die gefundenen Fehlerhinweise sind auch für Programmiereinsteiger
hilfreich, eine Optimierung der Performance und des Speicherverbrauches erfordert aber
weitergehende Kenntnisse in der Programmierung.
Abschließend kann festgestellt werden, dass JTest sich gut für Tests eignet, die parallel
zum Entwicklungsprozess vom Programmierteam selbst durchgeführt werden. Für die
Rettung von Projekten, die bereits in der abschließenden Testphase sind, ist JTest
ungeeignet. Die Produkte von Rational eignen sich eher für große Projekte, deren Tests
eine zentrale Instanz übernimmt und die sich auch in einem späteren Stadium befinden
können. Auch hier ist der Beginn des Testens so früh wie möglich ideal, aber auch
bereits in Schwierigkeiten befindliche Projekte lassen sich eventuell noch retten bzw.
verbessern.
17
Anhang
Anhang A
class Message {
private String messageText;
public String getMessageText() {
return messageText;
}
public void setMessageText(String m) {
messageText=m;
return;
}
public Message(String m) {
setMessageText(m);
return;
}
public boolean equals(Message m) {
return this.getMessageText().equals(m.getMessageText());
}
public void print() {
System.out.print(getMessageText());
return;
}
public void println() {
System.out.println(getMessageText());
return;
}
public static void main(String args[]) {
// Zum Test der Klasse
Message standardMessage=new Message("Hello World!");
standardMessage.println();
Message javaMessage=new Message("Hello Java!");
javaMessage.println();
System.out.println(standardMessage.equals(javaMessage));
return;
}
}
Quelle: http://www11.informatik.tu-muenchen.de/
~brueggem/Seminare/xmlUndJavaSS2000/JavaInBeispielen/javaBeispiele.html
18
Anhang
Anhang B
import
import
import
import
java.awt.*;
javax.swing.*;
javax.swing.border.*;
java.awt.event.*;
//
//
//
//
AWT classes
Swing components and classes
Borders for Swing components
Basic event handling
public class DisplayMessage {
public static void main(String[] args) {
JLabel msgLabel = new JLabel();
// Component to display the question
JButton yesButton = new JButton();// Button
JButton noButton = new JButton(); // Button
msgLabel.setText("Are you sure?");// The msg to display
msgLabel.setBorder(new EmptyBorder(10,10,10,10));
yesButton.setText((args.length >= 1)?args[0]:"Yes");
noButton.setText((args.length >= 2)?args[1]:"No");
JFrame win = new JFrame("Message");
JPanel buttonbox = new JPanel();
// The main application window
// A container for the buttons
win.getContentPane().setLayout(new BorderLayout());
buttonbox.setLayout(new FlowLayout
buttonbox.add(yesButton);
buttonbox.add(noButton);
// add yes button to the panel
// add no button to the panel
win.getContentPane().add(msgLabel, BorderLayout.CENTER);
win.getContentPane().add(buttonbox, BorderLayout.SOUTH);
yesButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Button 1 pressed");
}
});
noButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Button 2 pressed");
}
});
win.pack();
win.show();
}
}
Quelle: http://www11.informatik.tu-muenchen.de/
~brueggem/Seminare/xmlUndJavaSS2000/JavaInBeispielen/javaBeispiele.html
19
Anhang
Anhang C
package examples.eval;
public class Simple
{
public static int map (int index) {
switch (index) {
case 0:
case10:
return -1;
case 2:
case 20:
default:
return -2;
}
}
public static boolean startsWith (String str, String match) {
for (int i = 0; i < match.length (); ++i)
if (str.charAt (i) != match.charAt (i))
return false;
return true;
}
public static int add (int i1, int i2) {
return i1 + i2;
}
}
Quelle: JTest Tutorial, Bestandteil der Software
20
Anhang
Anhang D
package examples.eval;
import junit.framework.TestCase;
/**
* SimpleTest is a JUnit test for class examples.eval.Simple
*/
public class SimpleTest extends TestCase{
/**
* Constructs a test case for the test specified in the name argument.
*/
public SimpleTest (String name)
{
super (name);
/*
* This constructor should not be modified. Any initialization
* code should be placed in the setUp() method instead.
*/
}
/**
* Test for constructor: 'Simple ()'
*/
public void testSimple ()
{
/* Replace the default fail statement with your test code. */
fail ("Empty test case.");
}
/**
* Test for method: 'static boolean startsWith (String, String)'
*/
public void testStartsWith ()
{
/* Replace the default fail statement with your test code. */
fail ("Empty test case.");
}
/**
* Test for method: 'static int add (int, int)'
*/
public void testAdd ()
{
int result = 0;
result = Simple.add (5, 88);
assertTrue ("The result should be 93", result == 93);
}
/**
* Test for method: 'static int map (int)'
*/
public void testMap ()
{
/* Replace the default fail statement with your test code. */
fail ("Empty test case.");
}
21
Anhang
///////////////////
/**
* Used to set up the test. This method is called by JUnit before each
* of the tests are executed.
*/
protected void setUp ()
{
/* Add any necessary initialization code here (e.g., open a
socket). */
// _simple = new Simple ();
}
/**
* Used to clean up after the test. This method is called by JUnit
* after each of the tests has been completed.
*/
protected void tearDown ()
{
/* Add any necessary cleanup code here (e.g., close a socket). */
}
/*
* Uncomment this variable declaration and add any necessary
* initialization arguments for it in the setUp() method.
*/
// private Simple _simple;
/**
* Utility main method. This will the test cases defined in this
* class.
* Usage: java examples.eval.SimpleTest
*/
public static void main (String[] args)
{
/* junit.textui.TestRunner will write the test results to
stdout. */
junit.textui.TestRunner.run (SimpleTest.class);
/* junit.swingui.TestRunner will display the test results in
JUnit's swing interface. */
// junit.swingui.TestRunner.run (SimpleTest.class);
}
}
22
Literaturverzeichnis
[Be95]
Boris Beizer: Black Box Testing - Techniques for Functional Testing of
Software and Systems, John Wiley & Sons, 1995
[DbC04]
Homepage von Eiffel Software: http://www.eiffel.com/
[Ju04]
Homepage von JUnit: http://www.junit.org/index.htm
[Li02]
Peter Liggesmeyer: Software Qualität: Testen, Analysieren und Verifizieren
von Software, Spektrum, Akademischer Verlag, 2002.
[Pa04]
Homepage von Parasoft: http://www.parasoft.com/jsp/home.jsp
[Pa02]
Automatic Java Software and Component Testing – Using Jtest to Automate
Unit Testing and Coding Standard Enforcement, Parasoft, 2002
[Ra02]
PurifyPlus – Getting Started, Rational Software Corporation, 2002
[Ra04]
Homepage von Rational: http://www-306.ibm.com/software/rational/
Herunterladen