vierseitig

Werbung
8. Testautomatisierung
•
•
•
•
•
•
Was meint hier Automatisierung
• klassische Testansätze
– Entwicklung einer Testspezifikation (Vorbedingung,
Ausführung, erwartete Ergebnisse)
– manuelle Testausführung
– manuelle Erfassung und Auswertung der Testergebnisse
• erste Automatisierung
– Werkzeuge wie JUnit, Marathon erlauben die
automatische Testausführung und Protokollierung
(teilweise Auswertung)
– Werkzeuge müssen einzeln gestartet werden
• zweite Automatisierung
– mehrere Werkzeuge laufen nacheinander / zusammen
– Ergebnisse werden zentral protokolliert
Automatisierungsidee
Beispiele für Werkzeuge
Build-Server
Idee von Build-Werkzeugen
Einführung in Ant
Tests aus Ant starten
Software-Qualität
Stephan Kleuker
257
Werkzeuge - Beispiele (1/3): Ant
Stephan Kleuker
Stephan Kleuker
258
Werkzeuge - Beispiele (2/3): Maven
• Build-Prozess ist XML-Datei
• Build-Prozess als Baumstruktur (project, target, task)
• in Tasks steht, was mit welchem Werkzeug (Compiler,
JUnit, ...) wo gemacht werden soll
• für Java-Standardwerkzeuge sind Tasks bereits direkt in Ant
enthalten
• einige Werkzeuge bringen eigene Tasks zur Nutzung in Ant
mit (TestNG)
• Tasks selbst einfach in Java programmierbar
• Ant liefert keinen Standard-Build-Prozess (selbst schreiben)
• http://ant.apache.org/
Software-Qualität
Software-Qualität
259
• alle Projekteigenschaften in zentraler Datei pom.xml
• Project Object Model (mitgeliefert oder von Herstellern
geliefert)
• definiert Standard-Build-Prozess
• Artefakt-Repository (Verwaltung von Jars)
• Verwaltung der Projektabhängigkeiten (auch Beachtung
abhängiger Versionsnummern, mit Nachlademöglichkeiten)
• Build-Report als Website
• einfach erweiterbar
• deutlich mehr Einarbeitungsaufwand als Ant
• dann deutlich einfacher nutz- und wartbar als Ant
• http://maven.apache.org/
Software-Qualität
Stephan Kleuker
260
Build-Server
Werkzeuge - Beispiele (3/3): CruiseControl
• Software-Erstellung und Testdurchführung kann eigenen
Werkzeugen überlassen werden
• Möglichkeit zur kontinuierlichen Integration
• Führt Tests zu definierten Zeitpunkten aus; ermöglicht
einfache Regressionstests (Wiederholung alter Testfälle)
• Misst Testüberdeckung (kann mehrere Testwerkzeuge
zusammen nutzen)
• kann im Fehlerfall zuständige Personen benachrichtigen
• erstellt im Erfolgsfall auslieferbares Artefakt ( -> ArtefaktRepository)
•
•
•
•
•
•
•
•
CruiseControl configuration-Dateien in XML
Stößt Ant-, Maven- oder Batch-Builds an
kann andere Werkzeuge anstoßen (XCode)
Konsole als Web-Anwendung
Build-Log
Meldet Build-Ergebnis über Email, rss
gibt graphische Konfigurationswerkzeuge
http://cruisecontrol.sourceforge.net/
• Alternativen: Apache Gump, Anthill, Hudson, Continuum, ...
http://de.wikipedia.org/wiki/Kontinuierliche_Integration
Software-Qualität
Stephan Kleuker
261
Konzept von Ant (und make)
Software-Qualität
Stephan Kleuker
Erinnerung an make
• Es gibt zentrales Ziel (project) , was erreicht werden soll (z.
B. vollständige Kompilation)
• Jedes Ziel besteht aus Teilzielen (target), die vorher erreicht
werden müssen (z. B. Übersetzung eines Teilpakets)
• Werkzeug stellt Regeln auf, was in welcher Reihenfolge
gemacht werden muss, um zentrales Ziel zu erreichen
all : file1.o file2.o file3.o
gcc -o prog file1.o file2.o file3.o
• Werkzeug bietet dabei u. a.
– Reaktionsmöglichkeiten bei Fehlern
– Varianten bei der Ausführung
– Möglichkeit, Ordner zu löschen und anzulegen, Dateien
zu kopieren, verschieben und löschen
file2.o : file2.c
gcc -Wall -c file2.c
Software-Qualität
Stephan Kleuker
262
file1.o : file1.c
gcc -Wall -c file1.c
file3.o : file3.c
gcc -Wall -c file3.c
263
Software-Qualität
Stephan Kleuker
264
Beispiel für Abhängigkeiten
<target
<target
<target
<target
Ant-Basisskript (erzeugt von Eclipse)
name="init"/>
name="preprocess" depends="init"/>
name="compile" depends="init,preprocess"/>
name="package" depends="compile"/>
• Die Reihenfolge der Ziele (target) in der Datei hat keine
Bedeutung, nur „depends“ dabei wichtig
• Neben einem default-Ziel kann man beim Start ein Ziel
auswählen, z. B. compile
• alle depends betrachtet und schrittweise vom Werkzeug in
mögliche Reihenfolge gebracht, hier:
– init hat keine Abhängigkeiten, wird zuerst ausgeführt
(was, hier nicht sichtbar)
– preprocess benötigt init, da schon ausgeführt, wird nur
preprocess ausgeführt
Software-Qualität
Stephan Kleuker
265
Skript-Konstanten (Eigenschaften, Properties)
• Nutzung von Property-Werten mit ${eigen}
<property name= "db" value = "${eigen}.db"/>
• Bei Pfaden wird statt „value“ dann „location“ genutzt, dabei
werden / und \ automatisch angepasst
<property name="ziel" location="${p}/bla/fas"/>
<property name="ziel" location="${p}\bla\fas"/>
• Laufwerksbuchstaben, wie „C:“ sind verboten (möglichst mit
relativen Pfaden arbeiten)
• Es gibt vordefinierte Properties, z. B. ${user.home}, ${basedir}
Stephan Kleuker
Software-Qualität
Stephan Kleuker
266
Properies in Hilfsdatei build.properties
• <property name="eigen" value = "Wert" />
Software-Qualität
<?xml version="1.0"?>
<!-- =============================================
Projekt, Datum, Aufgabe Autor,
============================================= -->
<project name="project" default="default">
<description>
description
</description>
<!-- =================================
target: default
================================= -->
<target name="default" depends="depends"
description="--> description">
</target>
<!-- - - - - - - - - - - - - - - - - target: depends
- - - - - - - - - - - - - - - - - -->
<target name="depends">
</target>
</project>
267
# Properties für den JUnit-Testfall
# Basis-Verzeichnisse
src=${basedir}/src
build=${basedir}/build
lib=${basedir}/../../lib/fest-swing-1.2
report=${basedir}/report
# Quell-Verzeichnisse
src.junit=${src}/junit
# Verzeichnisse für generierte Artefakte
build.junit=${build}/junit
• in build.xml: <property file="build.properties" />
Software-Qualität
Stephan Kleuker
268
Hilfsmittel: Zeitstempel
Umgang mit Files und Dateien
• Einfachste Form: Task <tstamp/> , dann nutzbare Variablen:
– DSTAMP: aktuelles Datum, Default-Format yyyymmdd
– TSTAMP: aktuelle Uhrzeit, Default-Format hhmm
– TODAY: aktuelles Datum als String
• konfigurierbar über format-Property
<target name="zeigeZeit">
<tstamp>
<format property="TODAY"
pattern="dd.MMMM.yyyy" locale="de,DE"/>
</tstamp>
<echo message="DSTAMP = ${DSTAMP}"/>
<echo message="TSTAMP = ${TSTAMP}"/>
<echo message="TODAY = ${TODAY}"/>
</target>
[echo] DSTAMP = 20070209
[echo] TSTAMP = 1234
[echo] TODAY = 09.Februar.2007
Software-Qualität
Stephan Kleuker
269
Beispiel-target: Kompilieren
• weitere Parameter können der Ant-Dokumentation
entnommen werden (...\ant\docs\manual\index.html)
• classpath nur nutzen, wenn weitere Pakete genutzt werden
• echo hier als Spielerei
• Übersetzung aller Klassen in Verzeichnis src und
Unterverzeichnissen
Stephan Kleuker
<copy todir="archive">
<fileset dir="src">
<include name="*.java"/>
</fileset>
Software-Qualität
Stephan Kleuker
</copy>
270
Einbinden externer Bibliotheken
<!-- classpath in der Form besser weglassen! -->
<target name="compile"
depends="start"
description="kompiliere">
<javac srcdir="src"
destdir="build"
classpath="."
debug="on">
</javac>
<echo message="in compile"/>
</target>
Software-Qualität
• <mkdir dir="${builddir}"/>
– legt auch fehlende Unterverzeichnisse z. B. bei
/dist/nase/simpel/billig an
– übersprungen, falls Verzeichnis existiert
• <delete dir="${builddir}"/>
• <copy file="src/Hai.java" tofile="back/Hai.java"/>
• <move file="src/Hai.java" tofile="back/Hai.java"/>
• Pattern / Wildcards / reguläre Ausdrücke
– * für beliebig viele Zeichen
– ? für genau ein Zeichen
– ** alle Unterverzeichnisse, z. B. **/*.java
• häufig Property fileset zum Ein- und Ausschließen nutzbar
271
<path id="ExternalLibs">
<pathelement location="${lib}/junit-4.8.2.jar" />
<pathelement location="${lib}\extensions\junit\fest-swingjunit-4.5-1.2\fest-swing-junit-4.5-1.2.jar"/>
<pathelement location="${lib}/lib/fest-assert-1.2.jar" />
<pathelement location="${lib}/fest-mocks-1.0.jar" />
<pathelement location="${lib}/lib/fest-reflect-1.2.jar" />
<pathelement location="${lib}/fest-swing-1.2.jar" />
<pathelement location="${lib}/lib/fest-util-1.1.2.jar" />
</path>
<target name="compile" description="Sourcen kompilieren">
<javac srcdir="${src}" destdir="${build}">
<classpath refid="ExternalLibs" />
</javac>
</target>
Software-Qualität
Stephan Kleuker
272
Beispiel-target: Packen
Beispiel-target: JUnit ausführen
<target name="test" depends="compile"
description="JUnit-Test ausführen">
<junit printsummary="on" fork="yes">
<!-- classpath für die Ausführung setzen -->
<classpath>
<pathelement location="${build}" />
<path refid="ExternalLibs" />
</classpath>
<test name=„klicker.klickerTest" todir="${report}">
<formatter type="plain" usefile="true" />
</test>
</junit>
</target>
<!-- existierendes Manifest mit Attribut file="" -->
<target name="pack"
depends="compile"
description="packe">
<jar destfile="dist/gepackt.jar"
basedir="build">
<manifest>
<attribute name="Main-class"
value="de.kleuker.XStarter">
</attribute>
</manifest>
</jar>
<echo message="in pack"/>
</target>
• hier wird Manifest-Datei direkt erzeugt, zu nutzende Datei
kann auch angegeben werden
Software-Qualität
Stephan Kleuker
273
test-Task starten
Software-Qualität
Software-Qualität
Stephan Kleuker
274
Beispiel: Protokoll und Ergebnis
Stephan Kleuker
275
Software-Qualität
Stephan Kleuker
276
9. Metriken
•
•
•
•
•
•
Nutzung von Maßsystemen
• bisherigen Prüfverfahren sind aufwändig, besteht
Wunsch, schneller zu Qualitätsaussagen zu kommen
• Ansatz: Nutzung von Maßsystemen, die Zahlenwerte
generieren, deren Werte Indiz für Qualität der SW sind
• Werden Maße automatisch berechnet, kann man
Qualitätsforderungen stellen, dass bestimmte Maßzahlen
in bestimmten Bereichen liegen
• Wichtig ist, dass man weiß, dass nur Indikatoren
betrachtet werden, d.h. gewonnene Aussagen müssen
nachgeprüft werden
Idee von Maßsystemen
Halstead
live Variables
Variablenspanne
McCabe-Zahl
LCOM*
• Ähnliche Ansätze in der Projektverfolgung und Analyse
der Firmengesamtlage (-> Balanced Scorecard)
-> siehe Qualitätsmanagement
Software-Qualität
Stephan Kleuker
277
Metriken zur Ermittlung des Projektstands
Software-Qualität
Pakete
Stephan Kleuker
C1-Überdeckung
C2-Überdeckung
278
• Lines of Code pro Methode (LOC)
mögliche Grundregel: maximale Zahl unter 20
• Methoden pro Klasse
Die Zahl sollte zwischen 3 und 15 liegen
• Parameter pro Methode
Die Zahl sollte unter 6 liegen
• Exemplarvariablen pro Klasse
Die Zahl sollte unter 10 liegen [Entitäten ?]
• Abhängigkeiten zwischen Klassen
Keine Klasse sollte von mehr als vier Klassen abhängen
• weitere Maßzahlen z. B. Anzahl von Klassenvariablen und
Klassenmethoden
50%
Use
Cases
Stephan Kleuker
Grobe Metriken (Min, Max, Schnitt, Abweichung)
programmiert/
überdeckt
100%
0%
Software-Qualität
279
Software-Qualität
Stephan Kleuker
280
Halstead-Maße (1/2)
Halstead-Maße (2/2)
Basiert auf vier Größen
• N1: Gesamtzahl der verwendeten Operatoren (in Java z.B.
+,-,*,/,==,if,while,<Methodenname>)
• N2: Gesamtzahl der verwendeten Operanden (Variablen,
Konstante)
• n1: Anzahl der genutzten unterschiedlichen Operatoren
• n2: Anzahl der genutzten unterschiedlichen Operanden
• Größe des Vokabulars: n=n1+n2
• Länge der Implementation: N=N1+N2
if (k<2){
if (k>0) x=x*k;
}
Software-Qualität
unterschiedliche Operatoren: if ( < ) { > = * ; }
unterschiedliche Operanden: k 2 0 x
N1 = 13
N2 = 7
n1 = 10
n2 = 4
Stephan Kleuker
281
Live Variables
Software-Qualität
Stephan Kleuker
282
Variablenspanne
• Ansatz: Erstellung/Prüfung einer Anweisung umso
schwieriger, je mehr Variablen beachtet werden müssen
• Eine Variable heißt zwischen der ersten und der letzten
Nutzung lebendig
• Für Variable x: maximaler Abstand (in Code-Zeilen) zwischen
ihren Nutzungen. (Zeilennummer in der x zum (i+1)-ten Mal
minus Zeilennummer in der x zum i-ten Mal vorkommt.)
public static int mach(boolean a, boolean b){ //1
int x=0;
//2
if (a)
//3
x=2;
//4
else
a: 3-1=2
x=3;
//5
b: 6-1=5
if (b)
//6
x: 4-2=7-5=2
return(6/(x-3)); //7
else
Maximum: 5
return(6/(x-2)); //8
Durchschnitt: 3
}
public static int mach(boolean a, boolean b){
int x=0;
// a,b,x lebendig
if (a)
// a,b,x lebendig
x=2;
// b,x lebendig
else
x=3;
// b,x lebendig
if (b)
// b,x lebendig
return(6/(x-3)); // x lebendig
else
return(6/(x-2)); // x lebendig
}
• Interessant sind maximale und mittlere Zahl (Gesamtzahl
lebendiger Variablen durch Anzahl ausführbarer
Anweisungen) lebendiger Variablen
Software-Qualität
Berechnung von D (Schwierigkeiten ein Programm zu schreiben
oder zu verstehen)
n1 * N2
D = ------------------2 * n2
• D ist Funktion vom Vokabular und der Anzahl der Operanden
• Quotient N2 / n2 gibt die durchschnittliche Verwendung von
Operanden an
• Satz von Halstead: D beschreibt den Aufwand
– zum Schreiben von Programmen,
– den Aufwand bei Code- Reviews und
– das Verstehen von Programmen bei Wartungsvorgängen.
Anmerkung: Aufbauend auf den Basismetriken gibt es weitere
Metriken, die unterschiedliche Eigenschaften eines
Programms erfassen
Stephan Kleuker
• Wieder durchschnittlicher und maximaler Wert interessant
283
Software-Qualität
Stephan Kleuker
284
Zyklomatische Zahl nach McCabe
Beispiele für die zyklomatische Zahl
1. Man konstruiere die Kontrollflussgraphen
2. Man messe die strukturellen Komplexität
Die zyklomatische Zahl z(G) eines Kontrollflussgraphen G ist:
z(G) = e – n + 2 mit
e = Anzahl der Kanten des Kontrollflussgraphen
n = Anzahl der Knoten
Anzahl
Kanten
Anzahl
Knoten
McCabe
Zahl
Zyklomatische Komplexität gibt Obergrenze für die
Testfallanzahl für den Zweigüberdeckungstest an
In der Literatur wird 10 oft als maximal vertretbarer Wert
genommen (für OO-Programme geringer, z. B. 5)
für Java: #if + #do + #while + #switch-cases+ 1
Software-Qualität
Stephan Kleuker
285
Erweiterte McCabe-Zahl
0
2
4
3
6
1
3
4
3
5
1
1
2
2
3
Software-Qualität
Stephan Kleuker
286
Lack of Cohesion in Methods (LCOM*) - Ansatz
• Komplexität von Verzweigungen berücksichtigen
• gezählt werden alle Booleschen Bedingungen in
if(<Bedingung>) und while(<Bedingung>): anzahlBedingung
• gezählt werden alle Vorkommen von atomaren Prädikaten:
anzahlAtome
z. B.: ( a || x>3) && y<4 dann anzahlAtome=3
• erweitere McCabe-Zahl
ez(G) = z(G) + anZahlAtome - anzahlBedingung
• Frage: Gibt es Maß für gute Objektorientierung?
• Ansatz (Indikator): Exemplarvariablen sollten in mehreren
Methoden genutzt, möglichst kombiniert sein
• Hinweis: Es muss vorher festgelegt werden, ob
Klassenvariablen und Klassenmethoden berücksichtigt
werden sollen
• Was passiert, wenn man konsequent exzessiv OO macht
und auch in den Exemplarmethoden get() und set()
Methoden nutzt? Wie ist LCOM* dann rettbar?
• wenn nur atomare Bedingungen, z. B. if( x>4), dann gilt
ez(G) = z(G)
Software-Qualität
Stephan Kleuker
287
Software-Qualität
Stephan Kleuker
288
Lack of Cohesion in Methods (LCOM*) - Berechnung
LCOM*-Beispiel
public class LCOMSpielerei {
LCOM* = (avgNutzt–m) /(1-m)
• nutzt(a) die Zahl der Methoden, die eine Exemplarvariable
a der untersuchten Klasse nutzen
• sei avgNutzt der Durchschnitt aller Werte für alle
Exemplarvariablen
• sei m die Anzahl aller Methoden der untersuchten Klasse
• Ist der Wert nahe Null, handelt es sich um eine eng
zusammenhängende Klasse
• Ist der Wert nahe 1, ist die Klasse schwach
zusammenhängend, man sollte über eine Aufspaltung
nachdenken
private int a;
private int b;
private int c;
public void mach1(int x){
a=a+x;
}
public void mach2(int x){
a=a+x;
b=b-x;
}
public void mach3(int x){
a=a+x;
b=b-x;
für Eclipse gibt es Plugin Metrics
c=c+x;
http://sourceforge.net/projects/metrics/
}
berechnet u. A. erweiterte MCCabe-Zahl
und LCOM*
}
Software-Qualität
Stephan Kleuker
289
Beispiel eines Kivat-Diagramms
Maßzahlen können
graphisch dargestellt
werden, im KivatDiagramm steht jede
LOC
Achse für eine Metrik,
der weiße Bereich ist ok,
die anderen Bereiche
kritisch
Variablenspanne
Live Variables
Software-Qualität
Stephan Kleuker
nutzt(a)=3
nutzt(b)=2
nutzt(c)=1
avgNutzt=6/3=2
LCOM*= (2-3) /(1-3)
= -1/-2= 0.5
LCOM*
zyklomatische
Zahl
291
Software-Qualität
Stephan Kleuker
290
Herunterladen