SlideShare una empresa de Scribd logo
1 de 49
Groovy kind of Test 
5PSTUFO.BOESZ
© 2014 OPITZ CONSULTING Deutschland GmbH 
 
Motivation 
4QPDL(FCJN3BINFOEFS(SBJMT-FSOHSVQQF(. 
JOGBDIFVOEVTESVDLTTUBSLF5FTUT 
,BOOJDI4QPDL(FCBVDIJOFJOFNLMBTTJTDIFO+BWB1SPKFLUFJOTFU[FO
Was euch erwartet 
8BTJTU(SPPWZ  
8BTJTU4QPDL  
8BTJTU(FC  
8JFLBOOJDI4QPDL(FCJOFJOFNLMBTTJTDIFO+BWB1SPKFLUFJOTFU[FO
Was ihr nicht erwarten dürft 
6NGBOHSFJDIFJOG»ISVOHJO(SPPWZ 
SGBISVOHTCFSJDIUBVTFJOFNFDIUFO1SPKFLU 
BCHFTDIMPTTFOFT'PSTDIVOHTUIFNB
Warnung 
%JFTF1S£TFOUBUJPOLBOOTQVSFOWPO2VFMMDPEFFOUIBMUFO
Groovy
Was ist Groovy? 
+7.1SPHSBNNJFSVOE4LSJQU4QSBDIF 
FOUXJDLFMUJOWPO+BNFT4USBDIBO 
BMT+43JOEFO+BWB$PNNVOJUZ1SPDFTTBVGHFOPNNFO 
	HFMFJUFUWPO(VJMMBVNF-BGPSHF
 
0QFO4PVSDF
QBDIF4PGUXBSF-JDFOTF 
LUVFMMF7FSTJPO 
)PNFQBHFIUUQHSPPWZDPEFIBVTPSH
Groovy Design-Ziel 
%BT%FTJHO;JFMEFTVSTQS»OHMJDIFOOUXJDLMFST+BNFT4USBDIBOCFTUBOEEBSJO
 
FJOFÖHFTDIMJGGFOFÔ'BTTVOHEFS+BWB4ZOUBYNJUEFO,PO[FQUFOWPO3VCZ[V 
WFSCJOEFO 
2VFMMF8JLJQFEJB
Wichtigste Features 
FSXFJUFSU+BWB	EIH»MUJHFS+BWB$PEFJTUH»MUJHFS(SPPWZ$PEF

 
PQUJNJFSU+BWB	SFEV[JFSUVOOµUJHFO$PEF
TJOOWPMMF%FGBVMUT
 
LPNQJMJFSU[V+BWB#ZUF$PEF
M£VGUJOFJOFS+7.
 
JOUFHSJFSUTJDIQSPCMFNMPTNJUBOEFSFO+BWB,PNQPOFOUFO 
PQUJPOBMF5ZQJTJFSVOH 
/BUJWF6OUFSTU»U[VOHWPO$MPTVSFT
.BQT
-JTUFO
SFHVM£SFOVTES»DLFO
 
#JH%FDJNBMT
#JH*OUFHFST
6OJU5FTUJOH
.PDLJOH
 
SXFJUFSUF6OUFSTU»U[VOHWPO%#DDFTTVOE9.-+40/1SPDFTTJOH 
 

HJMUOJDIUHFOFSFMM
BCFSJOEFONFJTUFO'£MMFO
Beispiel: Array- bzw. List-Handling 
*O+BWB 
for (String it : new String [] { Rod, Carlos, Chris }) 
System.out.println(it); 
*O(SPPWZ 
[Rod, Carlos, Chris].each { println it }
Beispiel: Test 
class TrivialerTest { 
@Test 
def testet ein paar triviale Dinge() { 
assert 1 + 1 == 2 
assert 2 != 1 
} 
}
Spock
Was ist Spock? 
5FTUJOHVOE4QFDJGJDBUJPO'SBNFXPSLG»S+BWBVOE(SPPWZ 
*OUVJUJWFVOEBVTESVDLTTUBSLF%4- 
*OTQJSJFSUWPOWFSTDIJFEFOFO4QSBDIFOVOE'SBNFXPSLT 
	+6OJU
34QFD
K.PDL
.PDLJUP
(SPPWZ
4DBMB

 
)PNFQBHFIUUQTDPEFHPPHMFDPNQTQPDL
Specification 
5FTU,MBTTF
BCHFMFJUFUWPOspock.lang.Specification 
#FTUFIUBVT 
'JFMET	[#G»SEBT4ZTUFNVOEFS4QFDJGJDBUJPO
 
'JYUVSF.FUIPET	setup
cleanup
setupSpecVOEcleanupSpec
 
'FBUVSF.FUIPET	UFTUFOC[XCFTDISFJCFOEJF'FBUVSFT
 
)FMQFS.FUIPET
Phasen 
4FUVQ'JYUVSF 
4UJNVMVT 
7FSJGZ3FTQPOTF 
$MFBOVQ
Blocks 
%FGJOJFSFOEJF1IBTFO 
7FSXFOEVOHWPO+BWB 
7FSG»HCBSF#MµDLF 
setupPEFSgiven 
whenthenPEFSexpect 
cleanup 
where 
-BCFMFE4UBUFNFOUT
Beispiel: given when then 
class MathSpec extends spock.lang.Specification { 
def Maximum von zwei nummerischen Werten() { 
given: 
def a = 1 
def b = 5 
def c = 5 
when: 
def r = Math.max(a, b) 
then: 
r == c 
} 
}
Beispiel: expect 
class MathSpec extends spock.lang.Specification { 
def Maximum von zwei nummerischen Werten() { 
expect: 
Math.max(1, 5) == 5 
Math.max(2, 3) == 3 
} 
}
Beispiel: exception 
class MathSpec extends spock.lang.Specification { 
def Division durch 0 löst ArithmeticException aus() { 
when: 
1.0 / 0 
then: 
ArithmeticException e = thrown() 
e.message =~ Division 
} 
}
Beispiel: data-driven 
class MathSpec extends spock.lang.Specification { 
def Maximum von zwei nummerischen Werten() { 
expect: 
Math.max(value1, value2) == result 
where: 
value1  [1, 2, 3] 
value2  [5, 3, 7] 
result  [5, 3, 7] 
} 
}
Beispiel: data-table 
class MathSpec extends spock.lang.Specification { 
@Unroll(Maximum von #value1 und #value2 ist #result) 
def Maximum von zwei nummerischen Werten() { 
expect: 
Math.max(value1, value2) == result 
where: 
value1 | value2 | result 
1 | 5 | 5 
2 | 3 | 3 
7 | 3 | 7 
} 
}
Geb
Was ist Geb? 
VUPNBUJTJFSVOHTXFSL[FVHG»S8FC0CFSGM£DIFO 
	7FSZ(SPPWZ#SPXTFSBVUPNBUJPO
 
'PLVTBVGFJOGBDIFJOUVJUJWFOUXJDLMVOH 
)PNFQBHFIUUQXXXHFCJTIPSH
Best of breed 
Geb vereint... 
EJF4U£SLF.£DIUJHLFJUWPO8FC%SJWFS 
EJFMFHBO[JOGBDIIFJUWPO+2VFSZ$POUFOU4FMFDUJPO 
EJF3PCVTUIFJUEFT1BHF0CKFDU.PEFMMJOHT 
EJFVTESVDLTTU£SLFWPO(SPPWZ 
NQGPIMFO7FSXFOEVOHNJU4QPDL
Beispiel: Web 2.0 Taschenrechner 
IUUQXFCSFDIOFSEF
Beispiel - Scripting Ansatz 
def Addition von zwei Zahlen() { 
given: 
go http://web2.0rechner.de/ 
expect: 
title == Web 2.0 Taschenrechner 
when: 
$(a#num_1).click() 
$(a#A42).click() 
$(a#num_2).click() 
$(a#btn_equal).click() 
then: 
$(input#input).value() == 3 
}
Page-Object kapselt Seiten-Details 
class TaschenrechnerPage extends Page { 
static url = http://web2.0rechner.de/ 
static at = { title == Web 2.0 Taschenrechner } 
static content = { 
btn_1 { $(a#num_1) } 
btn_2 { $(a#num_2) } 
btn_add { $(a#A42) } 
btn_equals { $(a#btn_equal) } 
display { $(input#input) } 
} 
} 
IUUQXXXHFCJTIPSHNBOVBMDVSSFOUQBHFTIUNMQBHFT
Beispiel - Page-Object Ansatz 
def Addition von zwei Zahlen() { 
given: 
to TaschenrechnerPage 
when: 
btn_1.click() 
btn_add.click() 
btn_2.click() 
btn_equals.click() 
then: 
display.value() == 3 
}
Page-Object kapselt Funktionalität 
class TaschenrechnerPage extends Page { 
... 
static content = { 
btn { char c - $(a# + ids[c.toString()]) } 
result { display.value() } 
} 
def ids = [ 
1 : num_1, 
... 
+ : A42, 
= : btn_equal 
] 
def calculate( String formula ) { 
formula.chars.each { 
type it 
} 
type('=' as char) 
} 
def type( char character ) { 
btn(character).click() 
} 
}
Beispiel - Funktionale Spezifikation 
def Addition von zwei Zahlen() { 
given: 
to TaschenrechnerPage 
when: 
calculate(1+2) 
then: 
result == 3 
}
Beispiel - Spock Data-Table 
@Unroll(#formula ergibt #expectedResult) 
def Addition von zwei Zahlen() { 
given: 
to TaschenrechnerPage 
when: 
calculate(formula) 
then: 
result == expectedResult 
where: 
formula | expectedResult 
1+2 | 3 
2+3 | 6 
3+4 | 7 
4+5 | 9 
5+6 | 11 
}
Verwendung in einem 
Java Projekt
Beispiel Projekt 
*$0OMJOF	1PTUCBOL4ZTUFNT
 
.VMUJ.PEVM.BWFO1SPKFLU 
+BWB
4QSJOH
+1
+4'	3JDIGBDFT
 
TFQBSBUFT.BWFO.PEVMgroovy-functional-tests
Schritt 1 - trivialer Groovy Test 
Ziel: Maven Modul erweitern, 
so dass der folgende Groovy Test ausgeführt wird 
class TrivialerTest { 
@Test 
void testet ein paar triviale Dinge() { 
assert 1 + 1 == 2 
assert 2 != 1 
} 
}
Groovy  JUnit Dependency 
dependencies 
dependency 
groupidorg.codehaus.groovy/groupid 
artifactidgroovy-all/artifactid 
version2.2.1/version 
/dependency 
dependency 
groupidjunit/groupid 
artifactidjunit/artifactid 
version4.11/version 
/dependency 
/dependencies
Groovy Source Paths 
plugin 
groupidorg.codehaus.mojo/groupid 
artifactidbuild-helper-maven-plugin/artifactid 
version1.8/version 
executions 
execution 
idadd-source/id 
phasegenerate-sources/phase 
goalsgoaladd-source/goal/goals 
configuration 
sourcessourcesrc/main/groovy/sources 
/configuration 
/execution 
execution 
idadd-test-source/id 
phasegenerate-test-sources/phase 
goalsgoaladd-test-source/goal/goals 
configuration 
sourcessourcesrc/test/groovy/sources 
/configuration 
/execution 
/executions 
/plugin
Groovy Eclipse Compiler 
plugin 
artifactidmaven-compiler-plugin/artifactid 
version3.1/version 
configuration 
compileridgroovy-eclipse-compiler/compilerid 
/configuration 
dependencies 
dependency 
groupidorg.codehaus.groovy/groupid 
artifactidgroovy-eclipse-compiler/artifactid 
version2.8.0-01/version 
/dependency 
dependency 
groupidorg.codehaus.groovy/groupid 
artifactidgroovy-eclipse-batch/artifactid 
version2.1.8-01/version 
/dependency 
/dependencies 
/plugin 
IUUQEPDTDPEFIBVTPSHEJTQMBZ(3007:(SPPWZDMJQTF
DPNQJMFS
QMVHJO
GPS
.BWFO
Test Classes vs. Test Sources 
.BWFOTVDIUTUBOEBSEN£žJHJOEFO5FTU4PVSDFTOBDIKBWB5FTU%BUFJFO 
(SPPWZ%BUFJFO	NJU%BUFJFOEVOHHSPPWZ
XFSEFOEBIFSOJDIUHFGVOEFO 
.BWFOTPMMJOEFODPNQJMJFSUFO,MBTTFOOBDI5FTUTTVDIFO 
properties 
maven.test.search.classdirtrue/maven.test.search.classdir 
/properties
mvn verify 
... 
[INFO] --- maven-surefire-plugin:2.10:test (default-test) @ groovy-functional-tests --- 
[INFO] Surefire report directory: D:ProjekteGroovy_kind_of_TestSourcesgroovy-functional-tests 
targetsurefire-reports 
------------------------------------------------------- 
T E S T S 
------------------------------------------------------- 
Running de.javandry.groovyfunctionaltests.TrivialTest 
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.314 sec 
Results : 
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 
... 
[INFO] ------------------------------------------------------------------------ 
[INFO] BUILD SUCCESS 
[INFO] ------------------------------------------------------------------------
Schritt 2 - erste einfache Geb Spec 
Ziel: Maven Modul erweitern, so dass 
die folgende Geb Specification ausgeführt wird 
class LoginSpec extends GebReportingSpec { 
static final validCredentials = [username: 'pl2', password: '2lp'] 
def login with valid credentials() { 
given: 
to LoginPage 
when: 
loginWith validCredentials 
then: 
at IcUebersichtPage 
} 
}
LoginPage 
class LoginPage extends Page { 
static url = pages/login.xhtml 
static content = { 
username { $(#j_username) } 
password { $(#j_password) } 
loginButton { $(#loginButton) } 
} 
void loginWith(def credentials) { 
username = credentials.username 
password = credentials.password 
loginButton.click() 
} 
}
GebConfig.groovy 
baseUrl = http://localhost:8888/iconline/ 
reportsDir = target/surefire-reports/geb 
IUUQXXXHFCJTIPSHNBOVBMDVSSFOUDPOGJHVSBUJPOIUNMDPOGJHVSBUJPO
Spock  Geb Dependencies 
dependency 
groupidorg.spockframework/groupid 
artifactidspock-core/artifactid 
version0.7-groovy-2.0/version 
scopetest/scope 
/dependency 
dependency 
groupidorg.gebish/groupid 
artifactidgeb-spock/artifactid 
version0.9.2/version 
scopetest/scope 
/dependency 
dependency 
groupidorg.seleniumhq.selenium/groupid 
artifactidselenium-htmlunit-driver/artifactid 
version2.26.0/version 
scopetest/scope 
/dependency 
IUUQXXXHFCJTIPSHNBOVBMDVSSFOUJOUSPIUNMJOTUBMMBUJPO@@VTBHF
IC-Online Anwendung lokal starten 
*EFF%JFGVOLUJPOBMFO5FTUTUFTUFOEJFOXFOEVOHTP
XJFEFSOXFOEFSTJF 
BVDIWFSXFOEFOX»SEF
EIBVTTDIMJFžMJDI»CFSEJF0CFSGM£DIF 
7FSXFOEVOHEFT.BWFO$BSHP1MVHJOT 
4UBSUFOFJOFTMPLBMFO$POUBJOFST 
%FQMPZFOEFSOXFOEVOH
Ausführen von Specs mit Surefire 
plugin 
groupidorg.apache.maven.plugins/groupid 
artifactidmaven-surefire-plugin/artifactid 
version2.16/version 
executions 
execution 
idfunctional-tests/id 
phaseintegration-test/phase 
goals 
goaltest/goal 
/goals 
configuration 
includes 
include**/*Spec.class/include 
/includes 
/configuration 
/execution 
/executions 
/plugin 
IUUQNBWFOBQBDIFPSHTVSFGJSFNBWFOTVSFGJSFQMVHJOFYBNQMFTJODMVTJPOFYDMVTJPOIUNM

Más contenido relacionado

La actualidad más candente

R (Shiny Package) - Server Side Code for Decision Support System
R (Shiny Package) - Server Side Code for Decision Support SystemR (Shiny Package) - Server Side Code for Decision Support System
R (Shiny Package) - Server Side Code for Decision Support System
Maithreya Chakravarthula
 
R (Shiny Package) - UI Side Script for Decision Support System
R (Shiny Package) - UI Side Script for Decision Support SystemR (Shiny Package) - UI Side Script for Decision Support System
R (Shiny Package) - UI Side Script for Decision Support System
Maithreya Chakravarthula
 
jQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20PresentationjQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20Presentation
guestcf600a
 

La actualidad más candente (16)

The Ring programming language version 1.3 book - Part 33 of 88
The Ring programming language version 1.3 book - Part 33 of 88The Ring programming language version 1.3 book - Part 33 of 88
The Ring programming language version 1.3 book - Part 33 of 88
 
Baitap tkw
Baitap tkwBaitap tkw
Baitap tkw
 
R (Shiny Package) - Server Side Code for Decision Support System
R (Shiny Package) - Server Side Code for Decision Support SystemR (Shiny Package) - Server Side Code for Decision Support System
R (Shiny Package) - Server Side Code for Decision Support System
 
PHP webboard
PHP webboardPHP webboard
PHP webboard
 
The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184
 
PHP cart
PHP cartPHP cart
PHP cart
 
R (Shiny Package) - UI Side Script for Decision Support System
R (Shiny Package) - UI Side Script for Decision Support SystemR (Shiny Package) - UI Side Script for Decision Support System
R (Shiny Package) - UI Side Script for Decision Support System
 
Produce nice outputs for graphical, tabular and textual reporting in R-Report...
Produce nice outputs for graphical, tabular and textual reporting in R-Report...Produce nice outputs for graphical, tabular and textual reporting in R-Report...
Produce nice outputs for graphical, tabular and textual reporting in R-Report...
 
R for you
R for youR for you
R for you
 
Computer practicals(part) Class 12
Computer practicals(part) Class 12Computer practicals(part) Class 12
Computer practicals(part) Class 12
 
jQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20PresentationjQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20Presentation
 
Project hotel on hotel management fo
Project  hotel on hotel management foProject  hotel on hotel management fo
Project hotel on hotel management fo
 
The Ring programming language version 1.9 book - Part 52 of 210
The Ring programming language version 1.9 book - Part 52 of 210The Ring programming language version 1.9 book - Part 52 of 210
The Ring programming language version 1.9 book - Part 52 of 210
 
The Ring programming language version 1.7 book - Part 10 of 196
The Ring programming language version 1.7 book - Part 10 of 196The Ring programming language version 1.7 book - Part 10 of 196
The Ring programming language version 1.7 book - Part 10 of 196
 
The Ring programming language version 1.6 book - Part 9 of 189
The Ring programming language version 1.6 book - Part 9 of 189The Ring programming language version 1.6 book - Part 9 of 189
The Ring programming language version 1.6 book - Part 9 of 189
 
The Ring programming language version 1.5.4 book - Part 51 of 185
The Ring programming language version 1.5.4 book - Part 51 of 185The Ring programming language version 1.5.4 book - Part 51 of 185
The Ring programming language version 1.5.4 book - Part 51 of 185
 

Similar a Groovy kind of test

Bca sem 6 php practicals 1to12
Bca sem 6 php practicals 1to12Bca sem 6 php practicals 1to12
Bca sem 6 php practicals 1to12
Hitesh Patel
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 

Similar a Groovy kind of test (20)

Bca sem 6 php practicals 1to12
Bca sem 6 php practicals 1to12Bca sem 6 php practicals 1to12
Bca sem 6 php practicals 1to12
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 Autumn
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 AutumnGoptuna Distributed Bayesian Optimization Framework at Go Conference 2019 Autumn
Goptuna Distributed Bayesian Optimization Framework at Go Conference 2019 Autumn
 
Begin with Python
Begin with PythonBegin with Python
Begin with Python
 
Pdxpugday2010 pg90
Pdxpugday2010 pg90Pdxpugday2010 pg90
Pdxpugday2010 pg90
 
JQuery Flot
JQuery FlotJQuery Flot
JQuery Flot
 
CoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairCoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love Affair
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love Story
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love Story
 
Rntb20200805
Rntb20200805Rntb20200805
Rntb20200805
 
Nativescript angular
Nativescript angularNativescript angular
Nativescript angular
 
Advance java
Advance javaAdvance java
Advance java
 
PureScript & Pux
PureScript & PuxPureScript & Pux
PureScript & Pux
 
Apache Spark in your likeness - low and high level customization
Apache Spark in your likeness - low and high level customizationApache Spark in your likeness - low and high level customization
Apache Spark in your likeness - low and high level customization
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
준비하세요 Angular js 2.0
준비하세요 Angular js 2.0준비하세요 Angular js 2.0
준비하세요 Angular js 2.0
 
Django quickstart
Django quickstartDjango quickstart
Django quickstart
 
Practica n° 7
Practica n° 7Practica n° 7
Practica n° 7
 
Introduction to-mongo db-execution-plan-optimizer-final
Introduction to-mongo db-execution-plan-optimizer-finalIntroduction to-mongo db-execution-plan-optimizer-final
Introduction to-mongo db-execution-plan-optimizer-final
 
Introduction to Mongodb execution plan and optimizer
Introduction to Mongodb execution plan and optimizerIntroduction to Mongodb execution plan and optimizer
Introduction to Mongodb execution plan and optimizer
 

Más de OPITZ CONSULTING Deutschland

Más de OPITZ CONSULTING Deutschland (20)

OC|Webcast: Grundlagen der Oracle Lizenzierung
OC|Webcast: Grundlagen der Oracle LizenzierungOC|Webcast: Grundlagen der Oracle Lizenzierung
OC|Webcast: Grundlagen der Oracle Lizenzierung
 
OC|Webcast "Java heute" vom 28.09.2021
OC|Webcast "Java heute" vom 28.09.2021OC|Webcast "Java heute" vom 28.09.2021
OC|Webcast "Java heute" vom 28.09.2021
 
OC|Webcast "Java heute" vom 24.08.2021
OC|Webcast "Java heute" vom 24.08.2021OC|Webcast "Java heute" vom 24.08.2021
OC|Webcast "Java heute" vom 24.08.2021
 
OC|Webcast "Daten wirklich nutzen"
OC|Webcast "Daten wirklich nutzen"OC|Webcast "Daten wirklich nutzen"
OC|Webcast "Daten wirklich nutzen"
 
Architecture Room Stuttgart - "Cloud-native ist nur ein Teil des Spiels!"
Architecture Room Stuttgart - "Cloud-native ist nur ein Teil des Spiels!"Architecture Room Stuttgart - "Cloud-native ist nur ein Teil des Spiels!"
Architecture Room Stuttgart - "Cloud-native ist nur ein Teil des Spiels!"
 
OC|Webcast "Willkommen in der Cloud!"
OC|Webcast "Willkommen in der Cloud!"OC|Webcast "Willkommen in der Cloud!"
OC|Webcast "Willkommen in der Cloud!"
 
OC|Webcast "Die neue Welt der Virtualisierung"
OC|Webcast "Die neue Welt der Virtualisierung"OC|Webcast "Die neue Welt der Virtualisierung"
OC|Webcast "Die neue Welt der Virtualisierung"
 
10 Thesen zur professionellen Softwareentwicklung
10 Thesen zur professionellen Softwareentwicklung10 Thesen zur professionellen Softwareentwicklung
10 Thesen zur professionellen Softwareentwicklung
 
OC|Webcast: Oracle Lizenzierung - Lizenznews 2021
OC|Webcast: Oracle Lizenzierung - Lizenznews 2021OC|Webcast: Oracle Lizenzierung - Lizenznews 2021
OC|Webcast: Oracle Lizenzierung - Lizenznews 2021
 
OC|Webcast: Oracle Lizenzierung - Die größten Fallen in der Praxis
OC|Webcast: Oracle Lizenzierung - Die größten Fallen in der PraxisOC|Webcast: Oracle Lizenzierung - Die größten Fallen in der Praxis
OC|Webcast: Oracle Lizenzierung - Die größten Fallen in der Praxis
 
OC|Webcast: Oracle Lizenzierung - Virtualisierung und Cloud
OC|Webcast: Oracle Lizenzierung - Virtualisierung und CloudOC|Webcast: Oracle Lizenzierung - Virtualisierung und Cloud
OC|Webcast: Oracle Lizenzierung - Virtualisierung und Cloud
 
OC|Webcast: Grundlagen der Oracle-Lizenzierung
OC|Webcast: Grundlagen der Oracle-LizenzierungOC|Webcast: Grundlagen der Oracle-Lizenzierung
OC|Webcast: Grundlagen der Oracle-Lizenzierung
 
OC|Weekly Talk: Inspect’n’Adapt – Make Change come true!
OC|Weekly Talk: Inspect’n’Adapt – Make Change come true!OC|Weekly Talk: Inspect’n’Adapt – Make Change come true!
OC|Weekly Talk: Inspect’n’Adapt – Make Change come true!
 
OC|Webcast: Schnell und clever in die AWS Cloud – Migrationsszenarien und Han...
OC|Webcast: Schnell und clever in die AWS Cloud – Migrationsszenarien und Han...OC|Webcast: Schnell und clever in die AWS Cloud – Migrationsszenarien und Han...
OC|Webcast: Schnell und clever in die AWS Cloud – Migrationsszenarien und Han...
 
OC|Weekly Talk The Power of DevOps…
OC|Weekly Talk  The Power of DevOps…OC|Weekly Talk  The Power of DevOps…
OC|Weekly Talk The Power of DevOps…
 
OC|Weekly Talk: "Das müsste man mal digitalisieren" - Mit Low-Code schnell zu...
OC|Weekly Talk: "Das müsste man mal digitalisieren" - Mit Low-Code schnell zu...OC|Weekly Talk: "Das müsste man mal digitalisieren" - Mit Low-Code schnell zu...
OC|Weekly Talk: "Das müsste man mal digitalisieren" - Mit Low-Code schnell zu...
 
OC|Weekly Talk: Service Management – Was hat sich durch Corona geändert?
OC|Weekly Talk: Service Management – Was hat sich durch Corona geändert?OC|Weekly Talk: Service Management – Was hat sich durch Corona geändert?
OC|Weekly Talk: Service Management – Was hat sich durch Corona geändert?
 
OC|Weekly Talk - Digitales Coaching & Smart Sparring
OC|Weekly Talk - Digitales Coaching & Smart Sparring OC|Weekly Talk - Digitales Coaching & Smart Sparring
OC|Weekly Talk - Digitales Coaching & Smart Sparring
 
OC|Weekly Talk - Beratung remote
OC|Weekly Talk - Beratung remoteOC|Weekly Talk - Beratung remote
OC|Weekly Talk - Beratung remote
 
Effiziente Betriebsoptimierung durch Cloud Nutzung
Effiziente Betriebsoptimierung durch Cloud NutzungEffiziente Betriebsoptimierung durch Cloud Nutzung
Effiziente Betriebsoptimierung durch Cloud Nutzung
 

Último

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 

Último (20)

TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 

Groovy kind of test

  • 1. Groovy kind of Test 5PSTUFO.BOESZ
  • 2. © 2014 OPITZ CONSULTING Deutschland GmbH Motivation 4QPDL(FCJN3BINFOEFS(SBJMT-FSOHSVQQF(. JOGBDIFVOEVTESVDLTTUBSLF5FTUT ,BOOJDI4QPDL(FCBVDIJOFJOFNLMBTTJTDIFO+BWB1SPKFLUFJOTFU[FO
  • 3. Was euch erwartet 8BTJTU(SPPWZ 8BTJTU4QPDL 8BTJTU(FC 8JFLBOOJDI4QPDL(FCJOFJOFNLMBTTJTDIFO+BWB1SPKFLUFJOTFU[FO
  • 4. Was ihr nicht erwarten dürft 6NGBOHSFJDIFJOG»ISVOHJO(SPPWZ SGBISVOHTCFSJDIUBVTFJOFNFDIUFO1SPKFLU BCHFTDIMPTTFOFT'PSTDIVOHTUIFNB
  • 7. Was ist Groovy? +7.1SPHSBNNJFSVOE4LSJQU4QSBDIF FOUXJDLFMUJOWPO+BNFT4USBDIBO BMT+43JOEFO+BWB$PNNVOJUZ1SPDFTTBVGHFOPNNFO HFMFJUFUWPO(VJMMBVNF-BGPSHF 0QFO4PVSDF QBDIF4PGUXBSF-JDFOTF LUVFMMF7FSTJPO )PNFQBHFIUUQHSPPWZDPEFIBVTPSH
  • 8. Groovy Design-Ziel %BT%FTJHO;JFMEFTVSTQS»OHMJDIFOOUXJDLMFST+BNFT4USBDIBOCFTUBOEEBSJO FJOFÖHFTDIMJGGFOFÔ'BTTVOHEFS+BWB4ZOUBYNJUEFO,PO[FQUFOWPO3VCZ[V WFSCJOEFO 2VFMMF8JLJQFEJB
  • 9. Wichtigste Features FSXFJUFSU+BWB EIH»MUJHFS+BWB$PEFJTUH»MUJHFS(SPPWZ$PEF PQUJNJFSU+BWB SFEV[JFSUVOOµUJHFO$PEF TJOOWPMMF%FGBVMUT LPNQJMJFSU[V+BWB#ZUF$PEF M£VGUJOFJOFS+7. JOUFHSJFSUTJDIQSPCMFNMPTNJUBOEFSFO+BWB,PNQPOFOUFO PQUJPOBMF5ZQJTJFSVOH /BUJWF6OUFSTU»U[VOHWPO$MPTVSFT .BQT -JTUFO SFHVM£SFOVTES»DLFO #JH%FDJNBMT #JH*OUFHFST 6OJU5FTUJOH .PDLJOH SXFJUFSUF6OUFSTU»U[VOHWPO%#DDFTTVOE9.-+40/1SPDFTTJOH HJMUOJDIUHFOFSFMM BCFSJOEFONFJTUFO'£MMFO
  • 10. Beispiel: Array- bzw. List-Handling *O+BWB for (String it : new String [] { Rod, Carlos, Chris }) System.out.println(it); *O(SPPWZ [Rod, Carlos, Chris].each { println it }
  • 11. Beispiel: Test class TrivialerTest { @Test def testet ein paar triviale Dinge() { assert 1 + 1 == 2 assert 2 != 1 } }
  • 12. Spock
  • 13. Was ist Spock? 5FTUJOHVOE4QFDJGJDBUJPO'SBNFXPSLG»S+BWBVOE(SPPWZ *OUVJUJWFVOEBVTESVDLTTUBSLF%4- *OTQJSJFSUWPOWFSTDIJFEFOFO4QSBDIFOVOE'SBNFXPSLT +6OJU 34QFD K.PDL .PDLJUP (SPPWZ 4DBMB )PNFQBHFIUUQTDPEFHPPHMFDPNQTQPDL
  • 14. Specification 5FTU,MBTTF BCHFMFJUFUWPOspock.lang.Specification #FTUFIUBVT 'JFMET [#G»SEBT4ZTUFNVOEFS4QFDJGJDBUJPO 'JYUVSF.FUIPET setup cleanup setupSpecVOEcleanupSpec 'FBUVSF.FUIPET UFTUFOC[XCFTDISFJCFOEJF'FBUVSFT )FMQFS.FUIPET
  • 15. Phasen 4FUVQ'JYUVSF 4UJNVMVT 7FSJGZ3FTQPOTF $MFBOVQ
  • 16. Blocks %FGJOJFSFOEJF1IBTFO 7FSXFOEVOHWPO+BWB 7FSG»HCBSF#MµDLF setupPEFSgiven whenthenPEFSexpect cleanup where -BCFMFE4UBUFNFOUT
  • 17. Beispiel: given when then class MathSpec extends spock.lang.Specification { def Maximum von zwei nummerischen Werten() { given: def a = 1 def b = 5 def c = 5 when: def r = Math.max(a, b) then: r == c } }
  • 18. Beispiel: expect class MathSpec extends spock.lang.Specification { def Maximum von zwei nummerischen Werten() { expect: Math.max(1, 5) == 5 Math.max(2, 3) == 3 } }
  • 19. Beispiel: exception class MathSpec extends spock.lang.Specification { def Division durch 0 löst ArithmeticException aus() { when: 1.0 / 0 then: ArithmeticException e = thrown() e.message =~ Division } }
  • 20. Beispiel: data-driven class MathSpec extends spock.lang.Specification { def Maximum von zwei nummerischen Werten() { expect: Math.max(value1, value2) == result where: value1 [1, 2, 3] value2 [5, 3, 7] result [5, 3, 7] } }
  • 21. Beispiel: data-table class MathSpec extends spock.lang.Specification { @Unroll(Maximum von #value1 und #value2 ist #result) def Maximum von zwei nummerischen Werten() { expect: Math.max(value1, value2) == result where: value1 | value2 | result 1 | 5 | 5 2 | 3 | 3 7 | 3 | 7 } }
  • 22. Geb
  • 23. Was ist Geb? VUPNBUJTJFSVOHTXFSL[FVHG»S8FC0CFSGM£DIFO 7FSZ(SPPWZ#SPXTFSBVUPNBUJPO 'PLVTBVGFJOGBDIFJOUVJUJWFOUXJDLMVOH )PNFQBHFIUUQXXXHFCJTIPSH
  • 24. Best of breed Geb vereint... EJF4U£SLF.£DIUJHLFJUWPO8FC%SJWFS EJFMFHBO[JOGBDIIFJUWPO+2VFSZ$POUFOU4FMFDUJPO EJF3PCVTUIFJUEFT1BHF0CKFDU.PEFMMJOHT EJFVTESVDLTTU£SLFWPO(SPPWZ NQGPIMFO7FSXFOEVOHNJU4QPDL
  • 25. Beispiel: Web 2.0 Taschenrechner IUUQXFCSFDIOFSEF
  • 26. Beispiel - Scripting Ansatz def Addition von zwei Zahlen() { given: go http://web2.0rechner.de/ expect: title == Web 2.0 Taschenrechner when: $(a#num_1).click() $(a#A42).click() $(a#num_2).click() $(a#btn_equal).click() then: $(input#input).value() == 3 }
  • 27. Page-Object kapselt Seiten-Details class TaschenrechnerPage extends Page { static url = http://web2.0rechner.de/ static at = { title == Web 2.0 Taschenrechner } static content = { btn_1 { $(a#num_1) } btn_2 { $(a#num_2) } btn_add { $(a#A42) } btn_equals { $(a#btn_equal) } display { $(input#input) } } } IUUQXXXHFCJTIPSHNBOVBMDVSSFOUQBHFTIUNMQBHFT
  • 28. Beispiel - Page-Object Ansatz def Addition von zwei Zahlen() { given: to TaschenrechnerPage when: btn_1.click() btn_add.click() btn_2.click() btn_equals.click() then: display.value() == 3 }
  • 29. Page-Object kapselt Funktionalität class TaschenrechnerPage extends Page { ... static content = { btn { char c - $(a# + ids[c.toString()]) } result { display.value() } } def ids = [ 1 : num_1, ... + : A42, = : btn_equal ] def calculate( String formula ) { formula.chars.each { type it } type('=' as char) } def type( char character ) { btn(character).click() } }
  • 30. Beispiel - Funktionale Spezifikation def Addition von zwei Zahlen() { given: to TaschenrechnerPage when: calculate(1+2) then: result == 3 }
  • 31. Beispiel - Spock Data-Table @Unroll(#formula ergibt #expectedResult) def Addition von zwei Zahlen() { given: to TaschenrechnerPage when: calculate(formula) then: result == expectedResult where: formula | expectedResult 1+2 | 3 2+3 | 6 3+4 | 7 4+5 | 9 5+6 | 11 }
  • 32. Verwendung in einem Java Projekt
  • 33. Beispiel Projekt *$0OMJOF 1PTUCBOL4ZTUFNT .VMUJ.PEVM.BWFO1SPKFLU +BWB 4QSJOH +1 +4' 3JDIGBDFT TFQBSBUFT.BWFO.PEVMgroovy-functional-tests
  • 34. Schritt 1 - trivialer Groovy Test Ziel: Maven Modul erweitern, so dass der folgende Groovy Test ausgeführt wird class TrivialerTest { @Test void testet ein paar triviale Dinge() { assert 1 + 1 == 2 assert 2 != 1 } }
  • 35. Groovy JUnit Dependency dependencies dependency groupidorg.codehaus.groovy/groupid artifactidgroovy-all/artifactid version2.2.1/version /dependency dependency groupidjunit/groupid artifactidjunit/artifactid version4.11/version /dependency /dependencies
  • 36. Groovy Source Paths plugin groupidorg.codehaus.mojo/groupid artifactidbuild-helper-maven-plugin/artifactid version1.8/version executions execution idadd-source/id phasegenerate-sources/phase goalsgoaladd-source/goal/goals configuration sourcessourcesrc/main/groovy/sources /configuration /execution execution idadd-test-source/id phasegenerate-test-sources/phase goalsgoaladd-test-source/goal/goals configuration sourcessourcesrc/test/groovy/sources /configuration /execution /executions /plugin
  • 37. Groovy Eclipse Compiler plugin artifactidmaven-compiler-plugin/artifactid version3.1/version configuration compileridgroovy-eclipse-compiler/compilerid /configuration dependencies dependency groupidorg.codehaus.groovy/groupid artifactidgroovy-eclipse-compiler/artifactid version2.8.0-01/version /dependency dependency groupidorg.codehaus.groovy/groupid artifactidgroovy-eclipse-batch/artifactid version2.1.8-01/version /dependency /dependencies /plugin IUUQEPDTDPEFIBVTPSHEJTQMBZ(3007:(SPPWZDMJQTF
  • 40. GPS
  • 41. .BWFO
  • 42. Test Classes vs. Test Sources .BWFOTVDIUTUBOEBSEN£žJHJOEFO5FTU4PVSDFTOBDIKBWB5FTU%BUFJFO (SPPWZ%BUFJFO NJU%BUFJFOEVOHHSPPWZ XFSEFOEBIFSOJDIUHFGVOEFO .BWFOTPMMJOEFODPNQJMJFSUFO,MBTTFOOBDI5FTUTTVDIFO properties maven.test.search.classdirtrue/maven.test.search.classdir /properties
  • 43. mvn verify ... [INFO] --- maven-surefire-plugin:2.10:test (default-test) @ groovy-functional-tests --- [INFO] Surefire report directory: D:ProjekteGroovy_kind_of_TestSourcesgroovy-functional-tests targetsurefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running de.javandry.groovyfunctionaltests.TrivialTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.314 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
  • 44. Schritt 2 - erste einfache Geb Spec Ziel: Maven Modul erweitern, so dass die folgende Geb Specification ausgeführt wird class LoginSpec extends GebReportingSpec { static final validCredentials = [username: 'pl2', password: '2lp'] def login with valid credentials() { given: to LoginPage when: loginWith validCredentials then: at IcUebersichtPage } }
  • 45. LoginPage class LoginPage extends Page { static url = pages/login.xhtml static content = { username { $(#j_username) } password { $(#j_password) } loginButton { $(#loginButton) } } void loginWith(def credentials) { username = credentials.username password = credentials.password loginButton.click() } }
  • 46. GebConfig.groovy baseUrl = http://localhost:8888/iconline/ reportsDir = target/surefire-reports/geb IUUQXXXHFCJTIPSHNBOVBMDVSSFOUDPOGJHVSBUJPOIUNMDPOGJHVSBUJPO
  • 47. Spock Geb Dependencies dependency groupidorg.spockframework/groupid artifactidspock-core/artifactid version0.7-groovy-2.0/version scopetest/scope /dependency dependency groupidorg.gebish/groupid artifactidgeb-spock/artifactid version0.9.2/version scopetest/scope /dependency dependency groupidorg.seleniumhq.selenium/groupid artifactidselenium-htmlunit-driver/artifactid version2.26.0/version scopetest/scope /dependency IUUQXXXHFCJTIPSHNBOVBMDVSSFOUJOUSPIUNMJOTUBMMBUJPO@@VTBHF
  • 48. IC-Online Anwendung lokal starten *EFF%JFGVOLUJPOBMFO5FTUTUFTUFOEJFOXFOEVOHTP XJFEFSOXFOEFSTJF BVDIWFSXFOEFOX»SEF EIBVTTDIMJFžMJDI»CFSEJF0CFSGM£DIF 7FSXFOEVOHEFT.BWFO$BSHP1MVHJOT 4UBSUFOFJOFTMPLBMFO$POUBJOFST %FQMPZFOEFSOXFOEVOH
  • 49. Ausführen von Specs mit Surefire plugin groupidorg.apache.maven.plugins/groupid artifactidmaven-surefire-plugin/artifactid version2.16/version executions execution idfunctional-tests/id phaseintegration-test/phase goals goaltest/goal /goals configuration includes include**/*Spec.class/include /includes /configuration /execution /executions /plugin IUUQNBWFOBQBDIFPSHTVSFGJSFNBWFOTVSFGJSFQMVHJOFYBNQMFTJODMVTJPOFYDMVTJPOIUNM
  • 50. mvn verify ... [INFO] --- maven-surefire-plugin:2.16:test (functional-tests) @ groovy-functional-tests --- [INFO] Surefire report directory: D:ProjekteGroovy_kind_of_TestSources groovy-functional-teststargetsurefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running de.javandry.groovyfunctionaltests.LoginSpec ... Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.866 sec - in de.javandry.groovyfunctionaltests.LoginSpec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
  • 52. Wie geht's weiter? ;VTUBOEIFSTUFMMFO 7FSXFOEVOH+BWB5FTU%BUB#VJMEFS MUFSOBUJWF(SPPWZ5FTU%BUB#VJMEFS 6OJUVOE*OUFHSBUJPOTUFTUTWPO+BWB,MBTTFO (SPPWZ 4QPDL(FCJO+BWB.PEVMJOUFHSJFSFO
  • 53. Danke für eure Aufmerksamkeit