Post on 30-Aug-2019
Am besten Testen!
Professionelle Entwicklertests
Josef Adersberger @www.QAware.de
1
Ziel dieses Workshops…
• Sich, die Kollegen und das Managementfür Test-Driven-Development begeisternkönnen.
• Professionell mit JUnit umgehen können.
• Weitere Entwicklertest-Werkzeuge fürJava kennen und nutzen können.
2
Agenda J
3
Entwicklertests & TDD
4
Was sind Entwicklertests?= Alle Tests, die ein Entwickler
sinnvollerweise selbst macht.
• Aufgaben der Entwicklertests:• Müssen den Entwickler motivieren - the test infection!• Build Verifikation,
Kaffeepausen Validierung (Regression).• Arbeitsfortschritt dokumentieren
(RTF Metrik: Running, tested Features)• Die angenehmen Seiteneffekte:
Verbessert Dokumentation & Design.
5
Anforderungen an Entwicklertests
• A-TRIP(aus „Pragmatic Unit Testing“, Hunt/Thomas)
• Automated• Thorough• Repeatable• Independant• Professional
•Flexible•Fast•Designed
… und mein FFD:
6
Test Driven Development= Entwicklertests in Action
Klassischer (XP) Ansatz:Write test code to ask your system a question,write system code to respond to the questionand keep the dialogue going until you've programmed what you need.
Weniger extremer Ansatz; selber Spirit:Code a little, test a little
Failure OK
- Code vereinfachen- Code erweitern + Test erweitern
Bug
7
JUnit Grundlagen
8
JUnit• JUnit (www.junit.org) ist der Platzhirsch im Umfeld der
Automatisierungs-Frameworks für Unit-Tests• Entwicklung der Konzepte ursprünglich für Smalltalk (SUnit)• Entwicklung seit 1998;• Hauptentwickler sind Erich Gamma und Kent Beck• Umsetzung für viele Sprachen verfügbar:
CppUnit (C++), PyUnit (Python), NUnit (.NET), PHPUnit (PHP)
• Viele Erweiterungen für einzelne Testarten und zurArbeitserleichterung verfügbar
• Aktuell: Version 4.1 (hier wird noch die Version 3.8 betrachtet)
• Gute Alternative: TestNG (www.testng.org)
9
Das Framework: Basisklassen• Klassen-Hierarchie und eigener Testfall:
• Testfälle sind alle public void test<NAME>()Methoden innerhalb einer Subklasse von TestCase. DieKlasse selbst ist nur sterbliche Hülle.
10
Das Framework: Rote Ampel• Misserfolg eines Testfalls wird festgestellt durch:
• Asserts (Failure)• Exceptions (Error)
• Testmethoden dürfenbeliebigeExceptions werfen.
11
JUnit Grundlagen(1) TestCase Instanz wird per<CONSTRUCTOR>(String name)erzeugt
• Konvention: super(String name) aufrufen
(2) Methode setUp() wird aufgerufen• Konvention: super.setUp() aufrufen
(3) Eine Methode, deren Methodenname mit test beginntwird ausgeführt (Methodenname steckt in name)
(4) Methode tearDown() wird aufgerufen• Konvention: super.tearDown() aufrufen
(5) TestCase Instanz wird zerstört Dieser Vorgang wirdso lange wiederholt,bis alleTestmethoden einmalausgeführt wurden.
Dieser Vorgang wirdso lange wiederholt,bis alleTestmethoden einmalausgeführt wurden.
12
Beispiel: Das Test-Grundgerüst
13
Vorgehen: RightRight BICEP
• Right: Sind die Ergebnisse richtig?• Technik: Soll/Ist Vergleich
14
Right BBICEP
• Boundary condition: Sind die Grenzfällekorrekt?
• Technik: Äquivalenzklassen-Analyse
15
Äquivalenzklassen-Analyse
Wertebereiche / Mengen mit gleicher Wirkung (W)
ÄÄquivalenzklassenanalysequivalenzklassenanalyse
W1 W2 W3 W4 W5
GrenzwertanalyseGrenzwertanalyse
Problem: Was ist eine Wirkung?•Selber Rückgabewert•Selber Zustand•Gleiche Exception (Negativ-Test)
Normalwert Grenzwert ][Grenzwert ][
W3W2 W4
16
Right BIICEP
• Inverse operation: Können Sie dieumgekehrte Operation prüfen?
• Technik: Axiomatisches Testen
• Beispiel: add(A,B) == sub(A,-B)
17
Axiomatisches Testen• Vertrauensbereich schaffen
• Alle Methoden im JDK sind richtig• Alle einfachen Methoden sind richtig• Alle bereits getesteten Methoden sind richtig
• Neue Methoden auf Methoden desVertrauensbereichs zurückführen unddadurch testen.• Beispiel: a * b == a + a + … + a
18
Right BICCEP
• Cross-check: Können Sie eine Gegenprobemit den Ergebnissen machen?
• Technik: Axiomatisches Testen
19
Right BICEEP• Error condition: Können Sie Fehlersituationen
provozieren?• Technik:
• Äquivalenzklassen-Analyse• Schnittstellen-Verträge des Testlings analysieren und verletzen.
• @pre = Vorbedingung („gilt davor“)• @post = Nachbedingung („gilt danach“)• @inv = Invariante („gilt immer“)
20
Right BICEPP• Performance: Liegt die Performance im Bereich
des Erwarteten?
• Technik:• Kontinuierliche Messungen über die Entwicklungszeit• Komplexitätsprognose durch variable Eingabemenge• Harte Zeitschranken für Unit-Tests definieren
Performance
0
10
20
30
40
50
60
70
80
Jan 06 Feb 06 Mrz 06 Apr 06 Mai 06 Jun 06 Jul 06 Aug06
Sep06
Verlauf
Ausf
ühru
ngsz
eit (
ms)
Performance
21
JUnit Best-Practices
è Es müssen Best-Practices gesammelt und Konventionendefiniert werden!
JUnit is a typical toolkit:if used with care and with recognition of its idiosyncrasies,JUnit will help to develop good, robust tests. Used blindly,it may produce a pile of spaghetti instead of a test suite.(Andy Schneider –JavaWorld)
22
JUnit Best Practices• Asserts
• So viel Asserts wie möglich. Richtlinie ist mindestensein Assert pro Methodenaufruf am Testobjekt.
• Assert gleich verwenden, sobald die Bedingunggeprüft werden kann.
• Keine manuelle Überprüfung der Logging-Ausgaben.
MeldungErwarteter WertTestlauf-Wert
23
JUnit Best Practices• Benutzen Sie ein Logging-Framework stattSystem.out()• Ersetzt keine Asserts! Hilft aber beim Debugging von
Tests.• Logs sollten ausschaltbar / filterbar sein (Wichtig für
die Integration in den Build-Prozess)
24
JUnit Best Practices• Alle Initialisierungen in setUp() Methode
• Auch Konstruktor wird vor jedem Aufruf einerTestmethode aufgerufen.
• Exceptions im Konstruktor führen aber zu wenigaussagekräftigen Exception-Meldungen.
25
Weiterführende Themen
• Erweiterung (Dekoration) von Testläufen.• Testsuiten als Zusammenfassung von
Testfällen.• Testen in technischen Umgebungen
(Server, Dateisystem, UI, ...)
Siehe Literaturangaben am Ende…
26
Unsere Beispielanwendung
27
Gruppenspiel-Manager für Fussball WM 2010
• Innerhalb der Gruppen spielt jeder gegenjeden (3 Spiele pro Mannschaft).
• Ein Sieg bringt 3 Punkte, ein Remis 1 Punkt,eine Niederlage 0 Punkte.
• Die beiden Gruppenbesten sind qualifiziert.• Die Rangliste innerhalb einer Gruppe wird
wie folgt bestimmt:• Anzahl Punkte aus allen Gruppenspielen• Anzahl Punkte aus der Direktbegegnung• Tordifferenz aus der Direktbegegnung• Anzahl der erzielten Tore in Direktbegegnung• Tordifferenz aus allen Gruppenspielen• Anzahl der in allen Gruppenspielen erzielten
Tore• Entscheidungsspiel auf neutralem Platz
Siehe für WM 2006: http://www.fifa.com/documents/static/regulations/FWC06_regulations_DE.pdf
* Mit freundlicher Verwendung des Fair-Use Prinzips J
*
28
Die Beispielanwendung von ihrerSchokoladenseite
Group
+ registerTeam(ITeam) : void+ getTeam(String) : ITeam+ countRegisteredTeams() : int+ allTeamsRegistered() : boolean+ getResult(Pair) : Result+ addResult(Pair, Result) : void+ getActualOrder() : ITeam[]+ isFinished() : boolean
«interface»ITeam
~ getCountry() : String~ addPoints(Points) : int~ getPoints() : int~ addGoalsScored(int) : int~ addGoalsReceived(int) : int~ getGoalsScored() : int~ getGoalsReceived() : int
Team
ComparatorTeamComparator
+ TeamComparator(Group)+ compare(Object, Object) : int
dt::Pair
dt::Points
dt::Result
-group
29
Lab: JUnit Hands-OnZeitrahmen: 60min
• Implementierung der KlassenTeam, Pointsund der Schnittstelle ITeam.
• Gleichzeitig folgende Testfälleimplementieren:• testConstructor()• testEquals()• testAddPoints()• testAddGoals()
Team
- country: String- points: int = 0- goals_scored: int = 0- goals_received: int = 0
+ Team(String)+ getCountry() : String+ addPoints(Points) : int+ getPoints() : int+ addGoalsScored(int) : int+ addGoalsReceived(int) : int+ getGoalsScored() : int+ getGoalsReceived() : int+ toString() : String+ equals(Object) : boolean+ hashCode() : int
«interface»ITeam
~ getCountry() : String~ addPoints(Points) : int~ getPoints() : int~ addGoalsScored(int) : int~ addGoalsReceived(int) : int~ getGoalsScored() : int~ getGoalsReceived() : int
dt::Points
+ DEFEAT: Points = new Points(0) {readOnly}+ TIE: Points = new Points(1) {readOnly}+ VICTORY: Points = new Points(3) {readOnly}- points: int
- Points(int)+ points() : int+ equals(Object) : boolean+ hashCode() : int
30
Advanced Developer Testing
31
Meta TestsWie teste ich Tests?
• Faustregel: Alle 40 Zeilen Code enthalten(anfänglich) mindestens einen Fehler - dies giltauch für Tests.
• Test von Tests• Messung der Testüberdeckung• Test durch Sabotage• Statische Codeanalyse (z.B. Metrik Asserts pro
Testmethode)
32
C0 - Testüberdeckung• Anweisungsüberdeckung
• Berührte Knoten / Gesamt-Knoten
• Keine echte Qualitätsaussagefür den Test, aber Negativ-Aussage, wenn sehr niedrig!
• 100% Überdeckung wirdselten erreicht und ist auchteilweise nicht sinnvoll.
a
j
e
b
c
f
i
d
h
g
IF
IF
END IF
IF
WHILE
END IF
DO
a
j
e
b
c
f
i
d
h
g
IF
IF
END IF
IF
WHILE
END IF
DO
a
j
e
b
c
f
i
d
h
g
IF
IF
END IF
IF
WHILE
END IF
DO
a
j
e
b
c
f
i
d
h
g
IF
IF
END IF
IF
WHILE
END IF
DO
a, b, f, g, h, d, e= 100%
33
C1 - Überdeckung• Zweigüberdeckung
• Berührte Kanten / Gesamt Kanten
• Qualitätsaussage übereinen Test, aber keinKorrektheitsbeweis.
• Hoher Aufwand beiWert lim C1->100%
a
j
e
b
c
f
i
d
h
g
IF
IF
END IF
IF
WHILE
END IF
DO
a
j
e
b
c
f
i
d
h
g
IF
IF
END IF
IF
WHILE
END IF
DO
a
j
e
b
c
f
i
d
h
g
IF
IF
END IF
IF
WHILE
END IF
DO
a
j
e
b
c
f
i
d
h
g
IF
IF
END IF
IF
WHILE
END IF
DO
a,b,c,d,ea,b,f,g,i,g,h,d,e
a,j,e= 100%
34
Coverage Tools:Bewertungskriterien
• Plugins (Maven, Ant, Eclipse, intelliJ)• C-Level der Testüberdeckung
(C0 oft wenig aussagekräftig)• Qualität der Reports (Aggregation, Drill-Down)• Historie verfügbar?
35
Verfügbare Coverage Tools• JCoverage (teilw. kommerziell)
• Ant, Maven, Eclipse Plugins• C1
• Clover (kommerziell - Marktführer)• Eclipse, intelliJ, Ant, Maven Plugins• C1
• EMMA (frei)• Kommandozeile, Maven?, Ant?• C0
• Coverlipse (frei)• Eclipse• C0
• …
36
djUnit: JCoverage für Eclipse• Open Source Eclipse Plugin, das auf JCoverage basiert:
http://works.dgic.co.jp/djunit/index.html
Demo
37
Testüberdeckung
• Akzeptanzwerte sollten je nach Risiko fürjedes Testobjekt separat festgelegt werden.
• Testüberdeckung ist ideales Mittel um nochnicht getestete Codeteile zu finden.
38
Fit / FitNesse
• Fit: Ein Akzeptanztest-Framework• Kurzbeschreibung: Akzeptanztest-Framework• Download-URL: http://fit.c2.com/wiki.cgi?DownloadNow• Dokumentations-URL: http://fit.c2.com/wiki.cgi?FitDocumentation
• FitNesse: Wiki mit Anbindung an das Fit-Framework. Kollaborative Akzeptanztests.• Download-URL: http://www.fitnesse.org/FitNesse.DownLoad• Dokumentations-URL: http://www.fitnesse.org/FitNesse.UserGuide
Unit-Tests
Akzeptanz-Tests
Innensicht (White-Box, Wie?)
Außensicht (Black-Box, Was?)
Isolation
Integration
Kunde (Validierung)
Entwickler (Verifikation)
39
Fit/FitNesse: Die Idee
Anforderung
Tabelle A Tabelle B Tabelle C
Fixture A Fixture B Fixture C
Anwendung
Analysten /Fachbereich
Entwickler
Unittest A Unittest B Unittest C
Akzeptanz-tests
Wiki /HTML
Ab hier:Java
40
FitNesse-Checkunserer WM-Anwendung
Group
+ registerTeam(ITeam) : void+ getTeam(String) : ITeam+ countRegisteredTeams() : int+ allTeamsRegistered() : boolean+ getResult(Pair) : Result+ addResult(Pair, Result) : void+ getActualOrder() : ITeam[]+ isFinished() : boolean
41
Demo
42
Mock Objects• Mock Objects simulieren echte Objekte
• Attrappenhafte Implementierung von Schnittstellen• Funktionsreiche Mocks sind umstritten.
• Vorteile durch den Einsatz von Mock Objects:• Früheres Testen von integrierten Objekten• Reduzierte Abhängigkeiten von Entwicklungsarbeiten• Implizite Verbesserung des Anwendungs-Designs (lose Kopplung
und Trennung von Schnittstelle und Implementierung wirdgefördert)
• Mock-Frameworks:• EasyMock (http://www.easymock.org)• jMock (http://www.jmock.org)• rMock (http://rmock.sourceforge.net)• …
43
Beispiel: EasyMock
44
Ausblick und Zusammenfassung
45
AusblickWenn Sie in den Themen dieses Vortrags fit sind, dann
schauen Sie sich das an:
• Testdaten-Frameworks (DDSteps, … )• Technologie-Testframeworks
• HTTP, HTML• DB• XML
• Die nächste Generation• TestNG: JUnit++• JUnit 4.0: Annotationen statt Konventionen
• Einbettung in Build-Prozess
46
JUnit 4.0
47
TestNG
Version 4.x
48
Zusammenfassung
Schreiben Sie ihre Tests mit der gleichenProfessionalität, mit der Sie auch ihrenAnwendungscode schreiben – sie sind Teildavon!
49
Literaturtipps
50
Aufruf J• Bug Chasing in diesem Vortrag! Der Code der
Beispielanwendung steht ab heute Abend aufhttp://www.QAware.de zum Download.
• Der erste Bug-Einsender (belegt durch Testcase)erhält folgenden Literaturtipp:
an Josef.Adersberger@QAware.de
51
Links• JUnit FAQ
http://junit.sourceforge.net/doc/faq/faq.htm
• Artikel „Fit for Fun“ (Java Magazin 2.2006)http://javamagazin.de/itr/online_artikel/psecom,id,787,nodeid,11.html
• Vortrag „Next Generation Developer Testing;TestNG und JUnit 4.0 im Vergleich“ (JAX 2006)http://www.qaware.de/downloads/to1-adersberger.pdf