SlideShare ist ein Scribd-Unternehmen logo
1 von 46
Downloaden Sie, um offline zu lesen
David Völkel, @davidvoelkel 
Clean Test Code 
Clean Code Days 12.11.2014
2 
@davidvoelkel 
Entwickler & Consultant 
Software Craftsman 
Test-Driven Development 
Softwaredesign 
@softwerkskammer
Agil 
Automatisierte Tests 
=> häufige Releases + Qualität
Dirty Test Code 
technische Schulden 
Velocity sinkt 
Kosten 
Latenz 
agil
Clean Tests 
4 Eigenschaften verlässlich lesbar redundanzfrei fokussiert Fazit Fragen & Diskussion
xUnit- Patterns 
BDD 
Funktionale Tests 
setup 
arrange 
given 
Eingabe 
execute 
act 
when 
“Fixture“ 
verify 
assert 
then 
Ausgabe 
[teardown] 
[annihilate] 
Testphasen 
Input 
Output
4 Rules of Simple Design 
1.Pass all Tests 
2.Clear, Expressive & Consistent 
3.No Duplication 
4.Minimal Units
Verlässlich 
Gefahr Komplexität, vermeide 
•boolsche Assertions 
assertTrue(age >= 18);
Verlässlich 
Gefahr Komplexität, vermeide 
•boolsche Assertions 
assertTrue(age >= 18); 
assertThat(age, greaterThan(17))
Verlässlich 
Gefahr Komplexität vermeide 
•boolsche Assertions 
•Conditionals, komplexe Asserts & Schleifen 
boolean containsName = false; 
for (String name: names) { 
if (name.equals("David")) { 
containsName = true; 
} 
} 
assertTrue(containsName);
Verlässlich 
Gefahr Komplexität vermeide 
•boolsche Assertions 
•Conditionals, komplexe Asserts & Schleifen 
boolean containsName = false; 
for (String name: names) { 
if (name.equals("David")) { 
containsName = true; 
} 
} 
assertTrue(containsName); 
assertThat(names, hasItem("David"));
Lesbar 
„Write the tests you want to read“ 
80% lesen, 20% schreiben 
Executable Specifications 
Living Documentation
Abstraktion 
Weglassen von Details
Testmethode 
Gerard Meszaros: 
„When it is not important for something to be seen in the test method, it is important that it not be seen in the test method! “
„Im Bestellformular soll der Benutzer mit dem Abbrechen-Button den Bestellprozess beenden können”
@Test public void prozessAbbruch_inBestellFormular() { 
server.laufendeProzesse(0); 
ProzessStatus prozess = server.starteProzess(Prozess.BESTELLUNG); 
prozessInstanzId = prozess.getInstanzId(); 
server.laufendeProzesse(1); 
server.erwarteBenutzerFormular(prozessInstanzId, BESTELL_FORMULAR); 
Formular formular = new Formular(); 
formular.setBestellDatum("01.01.2015"); 
formular.setStandardVersand(false); 
String taskId = server.taskIdZu(prozessInstanzId); 
controller.submitEingabe(formular, 
Mockito.mock(BindingResult.class), null, 
taskId, null, ABBRUCH); 
server.laufendeProzesse(0); 
} 
„Im Bestellformular soll der Benutzer mit dem Abbrechen-Button den Bestellprozess beenden können”
@Test public void prozessAbbruch_inBestellFormular() { 
server.laufendeProzesse(0); 
ProzessStatus prozess = server.starteProzess(Prozess.BESTELLUNG); 
prozessInstanzId = prozess.getInstanzId(); 
server.laufendeProzesse(1); 
server.erwarteBenutzerFormular(prozessInstanzId, BESTELL_FORMULAR); 
Formular formular = new Formular(); 
formular.setBestellDatum("01.01.2015"); 
formular.setStandardVersand(false); 
String taskId = server.taskIdZu(prozessInstanzId); 
controller.submitEingabe(formular, 
Mockito.mock(BindingResult.class), null, 
taskId, null, ABBRUCH); 
server.laufendeProzesse(0); 
} 
„Im Bestellformular soll der Benutzer mit dem Abbrechen-Button den Bestellprozess beenden können” 
“Testskript” 
“Incidental Details”
@Test public void prozessAbbruch_inBestellFormular() { 
server.laufendeProzesse(0); 
ProzessStatus prozess = server.starteProzess(Prozess.BESTELLUNG); 
prozessInstanzId = prozess.getInstanzId(); 
server.laufendeProzesse(1); 
server.erwarteBenutzerFormular(prozessInstanzId, BESTELL_FORMULAR); 
Formular formular = new Formular(); 
formular.setBestellDatum("01.01.2015"); 
formular.setStandardVersand(false); 
String taskId = server.taskIdZu(prozessInstanzId); 
controller.submitEingabe(formular, 
Mockito.mock(BindingResult.class), null, 
taskId, null, server.laufendeProzesse(0); 
} 
ABBRUCH); 
Signal-Noise-Ratio? 
Single Level of Abstraction? 
„Im Bestellformular soll der Benutzer mit dem Abbrechen-Button den Bestellprozess beenden können”
@Test public void prozessAbbruch_inBestellFormular() { 
imFormular(BESTELL_FORMULAR); 
sendeFormularMitButton(ABBRUCH); 
prozessGestoppt(); 
} 
„Im Bestellformular soll der Benutzer mit dem Abbrechen-Button den Bestellprozess beenden können”
Namen
Name Testklasse 
public class AnOrderProcess { 
OrderProcess process; 
@Before public void createOrderProcess() { 
process = new OrderProcess(); 
} 
object under test
public class AnOrderProcess { 
OrderProcess process; 
@Before public void createOrderProcess() { 
process = new OrderProcess(); 
} 
@Test public void inOrderForm_cancel() { 
process.setState(ORDER_FORM); 
process.submit(CANCEL_BUTTON); 
assertThat("process canceled", process.isCanceled(), equalTo(true)); 
} 
Name Testmethode 
object under test
public class AnOrderProcess { 
OrderProcess process; 
@Before public void createOrderProcess() { 
process = new OrderProcess(); 
} 
@Test public void inOrderForm_cancel() { 
process.setState(ORDER_FORM); 
process.submit(CANCEL_BUTTON); 
assertThat("process canceled", process.isCanceled(), equalTo(true)); 
} 
Namen 
object under test 
setup
@Before public void createOrderProcess() { 
process = new OrderProcess(); 
} 
@Test public void inOrderForm_cancel() { 
process.setState(ORDER_FORM); 
process.submit(CANCEL_BUTTON); 
assertThat("process canceled", process.isCanceled(), equalTo(true)); 
} 
Namen 
setup 
execute
@Before public void createOrderProcess() { 
process = new OrderProcess(); 
} 
@Test public void inOrderForm_cancel() { 
process.setState(ORDER_FORM); 
process.submit(CANCEL_BUTTON); 
assertThat("process canceled", process.isCanceled(), equalTo(true)); 
} 
Namen 
setup 
execute 
verify
Publikum 
Test-Wartung 
Fehlersuche 
Spezifikation
Kommuniziere 
vollständig 
OuT + setup + execute + verify 
Verteilung: Klasse, Methoden-Name, Assertion
Redundanzfrei
@Rule 
public class BestellProzessTest { 
@Rule 
public ProzessTestServer server; 
} 
public class ProzessTestServer extends ExternalResource { 
@Override 
protected void before() throws Throwable { 
deployProcesses(); 
} 
@Override 
protected void after() { 
deleteAllProcessInstances(); 
}
Hierarchische Tests 
public class AnOrderProcess { 
@Before public void createOrderProcess() { 
process = new OrderProcess(); 
} 
public class InOrderForm { 
@Before public void inOrderForm() { 
process.setState(ORDER_FORM); 
} 
@Test public void whenCanceled_processIsStopped() { 
process.submit(CANCEL_BUTTON); 
assertThat("process stopped", process.isStopped(), equalTo(true)); 
} 
@Test public void whenBought_orderIsConfirmed() { 
process.submit(BUY_NOW_BUTTON); 
assertThat("state", process.getState(), equalTo(ORDER_CONFIRMED)); 
} 
} 
… 
gemeinsames 
“setup”
OuT 
Hierarchische Tests 
setup 
execute 
verify
Hilfsmethoden 
Object Mother 
Test Data Builder 
aCustomer("David"); 
CustomerTest.aCustomer("David"); 
CustomerMother.aCustomer("David"); 
CustomerMother.aCustomer("David", „Völkel"); 
CustomerMother.aCustomer(null, „Völkel", null, null, null, null, birthday); 
aCustomer().withLastName("Völkel") 
.withBirthDay(birthDay) 
.build(); 
Gemeinsame Testdaten
void assertMoneyEquals(Money expected, Money actual) { 
assertEquals("currency", expected.getCurrency(),actual.getCurrency()); 
assertEquals("amount", expected.getAmount(), actual.getAmount()); 
} 
Matcher<Money> equalTo(Money money) { 
return allOf( 
property(money, Money::getCurrency, "currency"), 
property(money, Money::getAmount, "amount")); 
} 
Hilfsmethoden 
Komposition via Hamcrest Matcher 
Gemeinsames Verify
"Single Concept per Test" 
"One Execute per Test" 
"One Assert per Test" 
Fokussiert
Parameterized „State of Java“ 
@Test public void beitragsfreiheit() { 
freigabeZustandIst(2, BEITRAGS_FREI); 
freigabeZustandIst(3, BEITRAGS_FREI); 
freigabeZustandIst(99, !BEITRAGS_FREI); 
freigabeZustandIst(null, !BEITRAGS_FREI); 
} 
Fokussiert
Status vs. Testbarkeit 
Fokussiert
„Listen to your tests!“ 
Hard to test code
Clean Tests 
wartbar 
lesbar 
flexibel 
verlässlich
Clean Tests 
wartbar 
lesbar 
flexibel 
verlässlich 
1. 
1.
Clean Tests 
wartbar 
Namen & 
Abstraktion 
lesbar 
flexibel 
verlässlich 
2.
Clean Tests 
wartbar 
redundanzfrei 
lesbar 
flexibel 
verlässlich 
3. 
Namen & 
Abstraktion
Clean Tests 
wartbar 
fokussiert 
redundanzfrei 
lesbar 
flexibel 
verlässlich 
4. 
Namen & 
Abstraktion
Fazit 
Agil bleiben mit Clean Test Code
Quellen 
Bücher 
„Clean Code“, Robert C. Martin 
„xUnit Test Patterns“, Gerard Meszaros 
„Effective Unittesting“, Lasse Koskela 
„Growing Object Oriented Software“, Steve Freeman, Nat Pryce 
„Specification by Example”, Gojko Adzic 
Videos 
Episoden 20-22 http://cleancoders.com/, 
Robert C. Martin 
Artikel 
„Design – jetzt auch für Tests“, David Völkel
David Völkel 
codecentric AG 
Twitter: @davidvoelkel 
david.voelkel@codecentric.de 
www.codecentric.de 
blog.codecentric.de 
Fragen und Diskussion 
45
Attribution-ShareAlike 3.0 Germany 
http://creativecommons.org/licenses/by-sa/3.0/de/ 
Die verwendeten Bilder sind gemeinfrei und stammen aus der Wikipedia 
Lizenz 
46

Weitere ähnliche Inhalte

Andere mochten auch

Wie wird mein Code testbar?
Wie wird mein Code testbar?Wie wird mein Code testbar?
Wie wird mein Code testbar?David Völkel
 
Mockist vs. Classicists TDD
Mockist vs. Classicists TDDMockist vs. Classicists TDD
Mockist vs. Classicists TDDDavid Völkel
 
Baby Steps TDD Approaches
Baby Steps TDD ApproachesBaby Steps TDD Approaches
Baby Steps TDD ApproachesDavid Völkel
 
Unit vs. Integration Tests
Unit vs. Integration TestsUnit vs. Integration Tests
Unit vs. Integration TestsDavid Völkel
 
Mockist vs Classicists TDD
Mockist vs Classicists TDDMockist vs Classicists TDD
Mockist vs Classicists TDDDavid Völkel
 
Integration Test Hell
Integration Test HellIntegration Test Hell
Integration Test HellDavid Völkel
 
Bad test, good test
Bad test, good testBad test, good test
Bad test, good testSeb Rose
 

Andere mochten auch (7)

Wie wird mein Code testbar?
Wie wird mein Code testbar?Wie wird mein Code testbar?
Wie wird mein Code testbar?
 
Mockist vs. Classicists TDD
Mockist vs. Classicists TDDMockist vs. Classicists TDD
Mockist vs. Classicists TDD
 
Baby Steps TDD Approaches
Baby Steps TDD ApproachesBaby Steps TDD Approaches
Baby Steps TDD Approaches
 
Unit vs. Integration Tests
Unit vs. Integration TestsUnit vs. Integration Tests
Unit vs. Integration Tests
 
Mockist vs Classicists TDD
Mockist vs Classicists TDDMockist vs Classicists TDD
Mockist vs Classicists TDD
 
Integration Test Hell
Integration Test HellIntegration Test Hell
Integration Test Hell
 
Bad test, good test
Bad test, good testBad test, good test
Bad test, good test
 

Ähnlich wie Clean Test Code (Clean Code Days)

Camunda@1&1
Camunda@1&1Camunda@1&1
Camunda@1&11&1
 
Testen im EE-Umfeld – Seien Sie feige!
Testen im EE-Umfeld – Seien Sie feige!Testen im EE-Umfeld – Seien Sie feige!
Testen im EE-Umfeld – Seien Sie feige!gedoplan
 
Einführung Software Testing und Qualitätssicherung
Einführung Software Testing und QualitätssicherungEinführung Software Testing und Qualitätssicherung
Einführung Software Testing und QualitätssicherungChristian Baranowski
 
Behaviour-Driven Development
Behaviour-Driven DevelopmentBehaviour-Driven Development
Behaviour-Driven Developmentjlink
 
Feige sein
Feige seinFeige sein
Feige seingedoplan
 
Prototype 1.7
Prototype 1.7Prototype 1.7
Prototype 1.7msebel
 
Bei uns testen lauter Affen - Das Ende der Banensoftware
Bei uns testen lauter Affen - Das Ende der BanensoftwareBei uns testen lauter Affen - Das Ende der Banensoftware
Bei uns testen lauter Affen - Das Ende der BanensoftwareSAP SE
 
E2E Tests mit PHP
E2E Tests mit PHPE2E Tests mit PHP
E2E Tests mit PHPkmhusseini
 
Testgetriebene Softwareentwicklung
Testgetriebene SoftwareentwicklungTestgetriebene Softwareentwicklung
Testgetriebene Softwareentwicklungjlink
 
Komponententests und Testabdeckung
Komponententests und TestabdeckungKomponententests und Testabdeckung
Komponententests und TestabdeckungChristian Baranowski
 
Hands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und StolperfallenHands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und Stolperfalleninovex GmbH
 
Mögen die Tests mit dir sein
Mögen die Tests mit dir seinMögen die Tests mit dir sein
Mögen die Tests mit dir seincodepitbull
 
Best Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptBest Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptSebastian Springer
 
MicroProfile 2.x: Der alternative Standard
MicroProfile 2.x: Der alternative StandardMicroProfile 2.x: Der alternative Standard
MicroProfile 2.x: Der alternative StandardOPEN KNOWLEDGE GmbH
 

Ähnlich wie Clean Test Code (Clean Code Days) (17)

Real Life TDD
Real Life TDDReal Life TDD
Real Life TDD
 
Camunda@1&1
Camunda@1&1Camunda@1&1
Camunda@1&1
 
Testen im EE-Umfeld – Seien Sie feige!
Testen im EE-Umfeld – Seien Sie feige!Testen im EE-Umfeld – Seien Sie feige!
Testen im EE-Umfeld – Seien Sie feige!
 
Einführung Software Testing und Qualitätssicherung
Einführung Software Testing und QualitätssicherungEinführung Software Testing und Qualitätssicherung
Einführung Software Testing und Qualitätssicherung
 
Behaviour-Driven Development
Behaviour-Driven DevelopmentBehaviour-Driven Development
Behaviour-Driven Development
 
Feige sein
Feige seinFeige sein
Feige sein
 
Prototype 1.7
Prototype 1.7Prototype 1.7
Prototype 1.7
 
Bei uns testen lauter Affen - Das Ende der Banensoftware
Bei uns testen lauter Affen - Das Ende der BanensoftwareBei uns testen lauter Affen - Das Ende der Banensoftware
Bei uns testen lauter Affen - Das Ende der Banensoftware
 
E2E Tests mit PHP
E2E Tests mit PHPE2E Tests mit PHP
E2E Tests mit PHP
 
Testgetriebene Softwareentwicklung
Testgetriebene SoftwareentwicklungTestgetriebene Softwareentwicklung
Testgetriebene Softwareentwicklung
 
Komponententests und Testabdeckung
Komponententests und TestabdeckungKomponententests und Testabdeckung
Komponententests und Testabdeckung
 
Hands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und StolperfallenHands-on Hystrix - Best Practices und Stolperfallen
Hands-on Hystrix - Best Practices und Stolperfallen
 
Mögen die Tests mit dir sein
Mögen die Tests mit dir seinMögen die Tests mit dir sein
Mögen die Tests mit dir sein
 
Best Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptBest Practices für TDD in JavaScript
Best Practices für TDD in JavaScript
 
T3ak12 extbase
T3ak12 extbaseT3ak12 extbase
T3ak12 extbase
 
MicroProfile 2.x: Der alternative Standard
MicroProfile 2.x: Der alternative StandardMicroProfile 2.x: Der alternative Standard
MicroProfile 2.x: Der alternative Standard
 
Tutorium 4
Tutorium 4Tutorium 4
Tutorium 4
 

Mehr von David Völkel

Die Kunst der kleinen Schritte - Softwerkskammer Lübeck
Die Kunst der kleinen Schritte - Softwerkskammer LübeckDie Kunst der kleinen Schritte - Softwerkskammer Lübeck
Die Kunst der kleinen Schritte - Softwerkskammer LübeckDavid Völkel
 
KPI Driven-Development in der Praxis - XP Days Germany
KPI Driven-Development in der Praxis - XP Days GermanyKPI Driven-Development in der Praxis - XP Days Germany
KPI Driven-Development in der Praxis - XP Days GermanyDavid Völkel
 
KPI-Driven-Development
KPI-Driven-DevelopmentKPI-Driven-Development
KPI-Driven-DevelopmentDavid Völkel
 
TDD Trade-Offs @Softwerkskammer Karlsruhe
TDD Trade-Offs @Softwerkskammer KarlsruheTDD Trade-Offs @Softwerkskammer Karlsruhe
TDD Trade-Offs @Softwerkskammer KarlsruheDavid Völkel
 
Global Day of Coderetreat Munich 2018
Global Day of Coderetreat Munich 2018Global Day of Coderetreat Munich 2018
Global Day of Coderetreat Munich 2018David Völkel
 
Die Kunst der kleinen Schritte - XP Days Germany 2018
Die Kunst der kleinen Schritte - XP Days Germany 2018Die Kunst der kleinen Schritte - XP Days Germany 2018
Die Kunst der kleinen Schritte - XP Days Germany 2018David Völkel
 
Global Day of Coderetreat Munich 2017
Global Day of Coderetreat Munich 2017Global Day of Coderetreat Munich 2017
Global Day of Coderetreat Munich 2017David Völkel
 
Fake It Outside-In TDD Workshop @ Clean Code Days
Fake It Outside-In TDD Workshop @ Clean Code Days Fake It Outside-In TDD Workshop @ Clean Code Days
Fake It Outside-In TDD Workshop @ Clean Code Days David Völkel
 
Fake It Outside-In TDD @XP2017
Fake It Outside-In TDD @XP2017Fake It Outside-In TDD @XP2017
Fake It Outside-In TDD @XP2017David Völkel
 
Fake It Outside-In TDD
Fake It Outside-In TDDFake It Outside-In TDD
Fake It Outside-In TDDDavid Völkel
 
Infrastructure as Code for Beginners
Infrastructure as Code for BeginnersInfrastructure as Code for Beginners
Infrastructure as Code for BeginnersDavid Völkel
 

Mehr von David Völkel (12)

Die Kunst der kleinen Schritte - Softwerkskammer Lübeck
Die Kunst der kleinen Schritte - Softwerkskammer LübeckDie Kunst der kleinen Schritte - Softwerkskammer Lübeck
Die Kunst der kleinen Schritte - Softwerkskammer Lübeck
 
KPI Driven-Development in der Praxis - XP Days Germany
KPI Driven-Development in der Praxis - XP Days GermanyKPI Driven-Development in der Praxis - XP Days Germany
KPI Driven-Development in der Praxis - XP Days Germany
 
KPI-Driven-Development
KPI-Driven-DevelopmentKPI-Driven-Development
KPI-Driven-Development
 
TDD Trade-Offs @Softwerkskammer Karlsruhe
TDD Trade-Offs @Softwerkskammer KarlsruheTDD Trade-Offs @Softwerkskammer Karlsruhe
TDD Trade-Offs @Softwerkskammer Karlsruhe
 
Global Day of Coderetreat Munich 2018
Global Day of Coderetreat Munich 2018Global Day of Coderetreat Munich 2018
Global Day of Coderetreat Munich 2018
 
Trade Off!
Trade Off!Trade Off!
Trade Off!
 
Die Kunst der kleinen Schritte - XP Days Germany 2018
Die Kunst der kleinen Schritte - XP Days Germany 2018Die Kunst der kleinen Schritte - XP Days Germany 2018
Die Kunst der kleinen Schritte - XP Days Germany 2018
 
Global Day of Coderetreat Munich 2017
Global Day of Coderetreat Munich 2017Global Day of Coderetreat Munich 2017
Global Day of Coderetreat Munich 2017
 
Fake It Outside-In TDD Workshop @ Clean Code Days
Fake It Outside-In TDD Workshop @ Clean Code Days Fake It Outside-In TDD Workshop @ Clean Code Days
Fake It Outside-In TDD Workshop @ Clean Code Days
 
Fake It Outside-In TDD @XP2017
Fake It Outside-In TDD @XP2017Fake It Outside-In TDD @XP2017
Fake It Outside-In TDD @XP2017
 
Fake It Outside-In TDD
Fake It Outside-In TDDFake It Outside-In TDD
Fake It Outside-In TDD
 
Infrastructure as Code for Beginners
Infrastructure as Code for BeginnersInfrastructure as Code for Beginners
Infrastructure as Code for Beginners
 

Kürzlich hochgeladen

Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...
Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...
Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...Markus Unterauer
 
Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...DNUG e.V.
 
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die CloudFrom Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die CloudOPEN KNOWLEDGE GmbH
 
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data ImputationFEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data ImputationOPEN KNOWLEDGE GmbH
 
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...OPEN KNOWLEDGE GmbH
 
Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...DNUG e.V.
 

Kürzlich hochgeladen (6)

Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...
Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...
Rückwärts denken vorwärts handeln - Requirements Reverse Engineering bei Syst...
 
Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (1) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
 
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die CloudFrom Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
 
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data ImputationFEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
 
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
 
Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
Slides (2) zu Teil 3 der Veranstaltungsreihe Anwendungsentwicklung mit Volt M...
 

Clean Test Code (Clean Code Days)

  • 1. David Völkel, @davidvoelkel Clean Test Code Clean Code Days 12.11.2014
  • 2. 2 @davidvoelkel Entwickler & Consultant Software Craftsman Test-Driven Development Softwaredesign @softwerkskammer
  • 3. Agil Automatisierte Tests => häufige Releases + Qualität
  • 4. Dirty Test Code technische Schulden Velocity sinkt Kosten Latenz agil
  • 5. Clean Tests 4 Eigenschaften verlässlich lesbar redundanzfrei fokussiert Fazit Fragen & Diskussion
  • 6. xUnit- Patterns BDD Funktionale Tests setup arrange given Eingabe execute act when “Fixture“ verify assert then Ausgabe [teardown] [annihilate] Testphasen Input Output
  • 7. 4 Rules of Simple Design 1.Pass all Tests 2.Clear, Expressive & Consistent 3.No Duplication 4.Minimal Units
  • 8. Verlässlich Gefahr Komplexität, vermeide •boolsche Assertions assertTrue(age >= 18);
  • 9. Verlässlich Gefahr Komplexität, vermeide •boolsche Assertions assertTrue(age >= 18); assertThat(age, greaterThan(17))
  • 10. Verlässlich Gefahr Komplexität vermeide •boolsche Assertions •Conditionals, komplexe Asserts & Schleifen boolean containsName = false; for (String name: names) { if (name.equals("David")) { containsName = true; } } assertTrue(containsName);
  • 11. Verlässlich Gefahr Komplexität vermeide •boolsche Assertions •Conditionals, komplexe Asserts & Schleifen boolean containsName = false; for (String name: names) { if (name.equals("David")) { containsName = true; } } assertTrue(containsName); assertThat(names, hasItem("David"));
  • 12. Lesbar „Write the tests you want to read“ 80% lesen, 20% schreiben Executable Specifications Living Documentation
  • 14. Testmethode Gerard Meszaros: „When it is not important for something to be seen in the test method, it is important that it not be seen in the test method! “
  • 15. „Im Bestellformular soll der Benutzer mit dem Abbrechen-Button den Bestellprozess beenden können”
  • 16. @Test public void prozessAbbruch_inBestellFormular() { server.laufendeProzesse(0); ProzessStatus prozess = server.starteProzess(Prozess.BESTELLUNG); prozessInstanzId = prozess.getInstanzId(); server.laufendeProzesse(1); server.erwarteBenutzerFormular(prozessInstanzId, BESTELL_FORMULAR); Formular formular = new Formular(); formular.setBestellDatum("01.01.2015"); formular.setStandardVersand(false); String taskId = server.taskIdZu(prozessInstanzId); controller.submitEingabe(formular, Mockito.mock(BindingResult.class), null, taskId, null, ABBRUCH); server.laufendeProzesse(0); } „Im Bestellformular soll der Benutzer mit dem Abbrechen-Button den Bestellprozess beenden können”
  • 17. @Test public void prozessAbbruch_inBestellFormular() { server.laufendeProzesse(0); ProzessStatus prozess = server.starteProzess(Prozess.BESTELLUNG); prozessInstanzId = prozess.getInstanzId(); server.laufendeProzesse(1); server.erwarteBenutzerFormular(prozessInstanzId, BESTELL_FORMULAR); Formular formular = new Formular(); formular.setBestellDatum("01.01.2015"); formular.setStandardVersand(false); String taskId = server.taskIdZu(prozessInstanzId); controller.submitEingabe(formular, Mockito.mock(BindingResult.class), null, taskId, null, ABBRUCH); server.laufendeProzesse(0); } „Im Bestellformular soll der Benutzer mit dem Abbrechen-Button den Bestellprozess beenden können” “Testskript” “Incidental Details”
  • 18. @Test public void prozessAbbruch_inBestellFormular() { server.laufendeProzesse(0); ProzessStatus prozess = server.starteProzess(Prozess.BESTELLUNG); prozessInstanzId = prozess.getInstanzId(); server.laufendeProzesse(1); server.erwarteBenutzerFormular(prozessInstanzId, BESTELL_FORMULAR); Formular formular = new Formular(); formular.setBestellDatum("01.01.2015"); formular.setStandardVersand(false); String taskId = server.taskIdZu(prozessInstanzId); controller.submitEingabe(formular, Mockito.mock(BindingResult.class), null, taskId, null, server.laufendeProzesse(0); } ABBRUCH); Signal-Noise-Ratio? Single Level of Abstraction? „Im Bestellformular soll der Benutzer mit dem Abbrechen-Button den Bestellprozess beenden können”
  • 19. @Test public void prozessAbbruch_inBestellFormular() { imFormular(BESTELL_FORMULAR); sendeFormularMitButton(ABBRUCH); prozessGestoppt(); } „Im Bestellformular soll der Benutzer mit dem Abbrechen-Button den Bestellprozess beenden können”
  • 20. Namen
  • 21. Name Testklasse public class AnOrderProcess { OrderProcess process; @Before public void createOrderProcess() { process = new OrderProcess(); } object under test
  • 22. public class AnOrderProcess { OrderProcess process; @Before public void createOrderProcess() { process = new OrderProcess(); } @Test public void inOrderForm_cancel() { process.setState(ORDER_FORM); process.submit(CANCEL_BUTTON); assertThat("process canceled", process.isCanceled(), equalTo(true)); } Name Testmethode object under test
  • 23. public class AnOrderProcess { OrderProcess process; @Before public void createOrderProcess() { process = new OrderProcess(); } @Test public void inOrderForm_cancel() { process.setState(ORDER_FORM); process.submit(CANCEL_BUTTON); assertThat("process canceled", process.isCanceled(), equalTo(true)); } Namen object under test setup
  • 24. @Before public void createOrderProcess() { process = new OrderProcess(); } @Test public void inOrderForm_cancel() { process.setState(ORDER_FORM); process.submit(CANCEL_BUTTON); assertThat("process canceled", process.isCanceled(), equalTo(true)); } Namen setup execute
  • 25. @Before public void createOrderProcess() { process = new OrderProcess(); } @Test public void inOrderForm_cancel() { process.setState(ORDER_FORM); process.submit(CANCEL_BUTTON); assertThat("process canceled", process.isCanceled(), equalTo(true)); } Namen setup execute verify
  • 27. Kommuniziere vollständig OuT + setup + execute + verify Verteilung: Klasse, Methoden-Name, Assertion
  • 29. @Rule public class BestellProzessTest { @Rule public ProzessTestServer server; } public class ProzessTestServer extends ExternalResource { @Override protected void before() throws Throwable { deployProcesses(); } @Override protected void after() { deleteAllProcessInstances(); }
  • 30. Hierarchische Tests public class AnOrderProcess { @Before public void createOrderProcess() { process = new OrderProcess(); } public class InOrderForm { @Before public void inOrderForm() { process.setState(ORDER_FORM); } @Test public void whenCanceled_processIsStopped() { process.submit(CANCEL_BUTTON); assertThat("process stopped", process.isStopped(), equalTo(true)); } @Test public void whenBought_orderIsConfirmed() { process.submit(BUY_NOW_BUTTON); assertThat("state", process.getState(), equalTo(ORDER_CONFIRMED)); } } … gemeinsames “setup”
  • 31. OuT Hierarchische Tests setup execute verify
  • 32. Hilfsmethoden Object Mother Test Data Builder aCustomer("David"); CustomerTest.aCustomer("David"); CustomerMother.aCustomer("David"); CustomerMother.aCustomer("David", „Völkel"); CustomerMother.aCustomer(null, „Völkel", null, null, null, null, birthday); aCustomer().withLastName("Völkel") .withBirthDay(birthDay) .build(); Gemeinsame Testdaten
  • 33. void assertMoneyEquals(Money expected, Money actual) { assertEquals("currency", expected.getCurrency(),actual.getCurrency()); assertEquals("amount", expected.getAmount(), actual.getAmount()); } Matcher<Money> equalTo(Money money) { return allOf( property(money, Money::getCurrency, "currency"), property(money, Money::getAmount, "amount")); } Hilfsmethoden Komposition via Hamcrest Matcher Gemeinsames Verify
  • 34. "Single Concept per Test" "One Execute per Test" "One Assert per Test" Fokussiert
  • 35. Parameterized „State of Java“ @Test public void beitragsfreiheit() { freigabeZustandIst(2, BEITRAGS_FREI); freigabeZustandIst(3, BEITRAGS_FREI); freigabeZustandIst(99, !BEITRAGS_FREI); freigabeZustandIst(null, !BEITRAGS_FREI); } Fokussiert
  • 37. „Listen to your tests!“ Hard to test code
  • 38. Clean Tests wartbar lesbar flexibel verlässlich
  • 39. Clean Tests wartbar lesbar flexibel verlässlich 1. 1.
  • 40. Clean Tests wartbar Namen & Abstraktion lesbar flexibel verlässlich 2.
  • 41. Clean Tests wartbar redundanzfrei lesbar flexibel verlässlich 3. Namen & Abstraktion
  • 42. Clean Tests wartbar fokussiert redundanzfrei lesbar flexibel verlässlich 4. Namen & Abstraktion
  • 43. Fazit Agil bleiben mit Clean Test Code
  • 44. Quellen Bücher „Clean Code“, Robert C. Martin „xUnit Test Patterns“, Gerard Meszaros „Effective Unittesting“, Lasse Koskela „Growing Object Oriented Software“, Steve Freeman, Nat Pryce „Specification by Example”, Gojko Adzic Videos Episoden 20-22 http://cleancoders.com/, Robert C. Martin Artikel „Design – jetzt auch für Tests“, David Völkel
  • 45. David Völkel codecentric AG Twitter: @davidvoelkel david.voelkel@codecentric.de www.codecentric.de blog.codecentric.de Fragen und Diskussion 45
  • 46. Attribution-ShareAlike 3.0 Germany http://creativecommons.org/licenses/by-sa/3.0/de/ Die verwendeten Bilder sind gemeinfrei und stammen aus der Wikipedia Lizenz 46