SlideShare ist ein Scribd-Unternehmen logo
1 von 36
Downloaden Sie, um offline zu lesen
David Völkel, @davidvoelkel 
Clean Test Code 
Agile Testing Days 11.11.2014
2 
@davidvoelkel 
Dev & Consultant 
Software Craftsman 
Test-Driven Development 
Software Design 
@softwerkskammer
Dirty Test Code 
technical debt 
velocity decrease 
costs 
latency 
agile
Clean Tests 
4 attributes reliable readable redundancy-free focused Conclusion Q&A
xUnit- Patterns 
BDD 
Functional tests 
setup 
arrange 
given 
Input rows 
execute 
act 
when 
“Fixture“ 
verify 
assert 
then 
Output rows 
[teardown] 
[annihilate] 
Test Phases 
Input 
Output
Reliable 
Mind complexity, so avoid 
•boolean assertions 
assertTrue(age >= 18); 
assertThat(age, greaterThan(17))
Reliable 
Mind complexity, so avoid 
•boolean assertions 
•conditionals & complex loops 
boolean containsName = false; 
for (String name: names) { 
if (name.equals("David")) { 
containsName = true; 
} 
} 
assertTrue(containsName); 
assertThat(names, hasItem("David"));
Readable 
Read >> write 
Executable specifications 
Living documentation
Abstraction 
avoid irrelevant details
Test Method Body 
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! “
“In the order form the user should be able to finish the order process by pressing the cancel button”
@Test public void cancelProcess_inOrderForm() { 
server.runningProcesses(0); 
ProcessStatus process = server.startProcess(Process.ORDER); 
processInstanceId = process.getInstanceId(); 
server.runningProcesses(1); 
server.expectUserForm(processInstanceId, ORDER_FORM); 
Form form = new Form(); 
form.setOrderDate("01.01.2015"); 
form.setStandardDelivery(false); 
String taskId = server.taskIdFor(processInstanceId); 
controller.submit(form, 
Mockito.mock(BindingResult.class), null, 
taskId, null, CANCEL); 
server.runningProcesses(0); 
} 
“In the order form the user should be able to finish the order process by pressing the cancel button”
@Test public void cancelProcess_inOrderForm() { 
server.runningProcesses(0); 
ProcessStatus process = server.startProcess(Process.ORDER); 
processInstanceId = process.getInstanceId(); 
server.runningProcesses(1); 
server.expectUserForm(processInstanceId, ORDER_FORM); 
Form form = new Form(); 
form.setOrderDate("01.01.2015"); 
form.setStandardDelivery(false); 
String taskId = server.taskIdFor(processInstanceId); 
controller.submit(form, 
Mockito.mock(BindingResult.class), null, 
taskId, null, CANCEL); 
server.runningProcesses(0); 
} 
“In the order form the user should be able to finish the order process by pressing the cancel button” 
„Testscript“ 
“Incidental Details”
@Test public void cancelProcess_inOrderForm() { 
server.runningProcesses(0); 
ProcessStatus process = server.stareProcess(Process.ORDER); 
processInstanceId = process.getInstanceId(); 
server.runningProcesses(1); 
server.expectUserForm(processInstanceId, ORDER_FORM); 
Form form = new Form(); 
form.setOrderDate("01.01.2015"); 
form.setStandardDelivery(false); 
String taskId = server.taskIdFor(processInstanceId); 
controller.submit(form, 
Mockito.mock(BindingResult.class), null, 
taskId, null, CANCEL); 
server.runningProcesses(0); 
} 
FORM 
CANCEL 
Signal-Noise-Ratio? 
Single Level of Abstraction? 
“In the order form the user should be able to finish the order process by pressing the cancel button”
@Test public void cancelProcess_inOrderForm() { 
inForm(ORDER_FORM); 
submitFormWithButton(CANCEL); 
noProcessRunning(); 
} 
“In the order form the user should be able to finish the order process by pressing the cancel button”
Names
Test class names 
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)); 
} 
Test method names 
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)); 
} 
Test method names 
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)); 
} 
Test method names 
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)); 
} 
Test method names 
setup 
execute 
verify
Audience? 
test maintainer 
search test failure cause 
business
Communicate 
comprehensively 
OuT + setup + execute + verify 
Distribute: Class, method name, verify
Redundancy-free
Hierarchical 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)); 
} 
} 
… 
extract common 
setup
OuT 
Hierarchical tests 
setup 
execute 
verify
Helper methods 
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(); 
Common test data
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")); 
} 
Custom asserts via helper methods 
Composed Hamcrest Matchers 
Common verify
"Single Concept per Test" 
"One Execute per Test" 
"One Assert per Test" 
Focused
State vs. testability 
Focused
„Listen to your tests!“ 
Hard-to-test Code
Clean Tests 
1.reliable 
2.readable 
3.redundancy-free 
4.focussed
Clean Test Code, 
stay agile!
Resources 
Books 
„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 
Episodes 20-22 http://cleancoders.com/, 
Robert C. Martin
David Völkel 
codecentric AG 
Twitter: @davidvoelkel 
david.voelkel@codecentric.de 
www.codecentric.de 
blog.codecentric.de 
Q&A 
35
Creative Commons ShareAlike 4.0 
The images used are public domain and can be found on Wikipedia. 
License 
36

Weitere ähnliche Inhalte

Was ist angesagt?

Testdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinnerTestdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinnerTruls Jørgensen
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS ProgrammersDavid Rodenas
 
Selenium my sql and junit user guide
Selenium my sql and junit user guideSelenium my sql and junit user guide
Selenium my sql and junit user guideFahad Shiekh
 
The Sky is Not Falling: Scaling Experimentation for Product Development
The Sky is Not Falling: Scaling Experimentation for Product DevelopmentThe Sky is Not Falling: Scaling Experimentation for Product Development
The Sky is Not Falling: Scaling Experimentation for Product DevelopmentOptimizely
 
COScheduler In Depth
COScheduler In DepthCOScheduler In Depth
COScheduler In DepthWO Community
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql JOYITAKUNDU1
 
Tech In Asia PDC 2017 - Best practice unit testing in mobile apps
Tech In Asia PDC 2017 - Best practice unit testing in mobile appsTech In Asia PDC 2017 - Best practice unit testing in mobile apps
Tech In Asia PDC 2017 - Best practice unit testing in mobile appsFandy Gotama
 
"Unit Testing for Mobile App" by Fandy Gotama (OLX Indonesia)
"Unit Testing for Mobile App" by Fandy Gotama  (OLX Indonesia)"Unit Testing for Mobile App" by Fandy Gotama  (OLX Indonesia)
"Unit Testing for Mobile App" by Fandy Gotama (OLX Indonesia)Tech in Asia ID
 
Deploying Straight to Production
Deploying Straight to ProductionDeploying Straight to Production
Deploying Straight to ProductionMark Baker
 
The secret unit testing tools no one has ever told you about
The secret unit testing tools no one has ever told you aboutThe secret unit testing tools no one has ever told you about
The secret unit testing tools no one has ever told you aboutDror Helper
 
Create a Customized GMF DnD Framework
Create a Customized GMF DnD FrameworkCreate a Customized GMF DnD Framework
Create a Customized GMF DnD FrameworkKaniska Mandal
 
Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:how to write unit test for new cod...
Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:how to write unit test for new cod...Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:how to write unit test for new cod...
Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:how to write unit test for new cod...LetAgileFly
 
Test-driven Development with AEM
Test-driven Development with AEMTest-driven Development with AEM
Test-driven Development with AEMJan Wloka
 
Unit Testing: Special Cases
Unit Testing: Special CasesUnit Testing: Special Cases
Unit Testing: Special CasesCiklum Ukraine
 
Uma introdução ao framework Spring
Uma introdução ao framework SpringUma introdução ao framework Spring
Uma introdução ao framework Springelliando dias
 
Unit test candidate solutions
Unit test candidate solutionsUnit test candidate solutions
Unit test candidate solutionsbenewu
 

Was ist angesagt? (20)

Testdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinnerTestdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinner
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS Programmers
 
Selenium my sql and junit user guide
Selenium my sql and junit user guideSelenium my sql and junit user guide
Selenium my sql and junit user guide
 
Mpg Dec07 Gian Lorenzetto
Mpg Dec07 Gian Lorenzetto Mpg Dec07 Gian Lorenzetto
Mpg Dec07 Gian Lorenzetto
 
The Sky is Not Falling: Scaling Experimentation for Product Development
The Sky is Not Falling: Scaling Experimentation for Product DevelopmentThe Sky is Not Falling: Scaling Experimentation for Product Development
The Sky is Not Falling: Scaling Experimentation for Product Development
 
COScheduler In Depth
COScheduler In DepthCOScheduler In Depth
COScheduler In Depth
 
Clean code
Clean codeClean code
Clean code
 
JS and patterns
JS and patternsJS and patterns
JS and patterns
 
Test
TestTest
Test
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql
 
Tech In Asia PDC 2017 - Best practice unit testing in mobile apps
Tech In Asia PDC 2017 - Best practice unit testing in mobile appsTech In Asia PDC 2017 - Best practice unit testing in mobile apps
Tech In Asia PDC 2017 - Best practice unit testing in mobile apps
 
"Unit Testing for Mobile App" by Fandy Gotama (OLX Indonesia)
"Unit Testing for Mobile App" by Fandy Gotama  (OLX Indonesia)"Unit Testing for Mobile App" by Fandy Gotama  (OLX Indonesia)
"Unit Testing for Mobile App" by Fandy Gotama (OLX Indonesia)
 
Deploying Straight to Production
Deploying Straight to ProductionDeploying Straight to Production
Deploying Straight to Production
 
The secret unit testing tools no one has ever told you about
The secret unit testing tools no one has ever told you aboutThe secret unit testing tools no one has ever told you about
The secret unit testing tools no one has ever told you about
 
Create a Customized GMF DnD Framework
Create a Customized GMF DnD FrameworkCreate a Customized GMF DnD Framework
Create a Customized GMF DnD Framework
 
Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:how to write unit test for new cod...
Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:how to write unit test for new cod...Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:how to write unit test for new cod...
Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:how to write unit test for new cod...
 
Test-driven Development with AEM
Test-driven Development with AEMTest-driven Development with AEM
Test-driven Development with AEM
 
Unit Testing: Special Cases
Unit Testing: Special CasesUnit Testing: Special Cases
Unit Testing: Special Cases
 
Uma introdução ao framework Spring
Uma introdução ao framework SpringUma introdução ao framework Spring
Uma introdução ao framework Spring
 
Unit test candidate solutions
Unit test candidate solutionsUnit test candidate solutions
Unit test candidate solutions
 

Andere mochten auch

Wann soll ich mocken?
Wann soll ich mocken?Wann soll ich mocken?
Wann soll ich mocken?David Völkel
 
Mockist vs. Classicists TDD
Mockist vs. Classicists TDDMockist vs. Classicists TDD
Mockist vs. Classicists TDDDavid Völkel
 
Transformation Priority Premise @Softwerkskammer MUC
Transformation Priority Premise @Softwerkskammer MUCTransformation Priority Premise @Softwerkskammer MUC
Transformation Priority Premise @Softwerkskammer MUCDavid Völkel
 
Clean Test Code (Clean Code Days)
Clean Test Code (Clean Code Days)Clean Test Code (Clean Code Days)
Clean Test Code (Clean Code Days)David Völkel
 
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 (11)

Wann soll ich mocken?
Wann soll ich mocken?Wann soll ich mocken?
Wann soll ich mocken?
 
Mockist vs. Classicists TDD
Mockist vs. Classicists TDDMockist vs. Classicists TDD
Mockist vs. Classicists TDD
 
Transformation Priority Premise @Softwerkskammer MUC
Transformation Priority Premise @Softwerkskammer MUCTransformation Priority Premise @Softwerkskammer MUC
Transformation Priority Premise @Softwerkskammer MUC
 
Clean Test Code (Clean Code Days)
Clean Test Code (Clean Code Days)Clean Test Code (Clean Code Days)
Clean Test Code (Clean Code Days)
 
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

The secret unit testing tools no one ever told you about
The secret unit testing tools no one ever told you aboutThe secret unit testing tools no one ever told you about
The secret unit testing tools no one ever told you aboutDror Helper
 
1 aleksandr gritsevski - attd example using
1   aleksandr gritsevski - attd example using1   aleksandr gritsevski - attd example using
1 aleksandr gritsevski - attd example usingIevgenii Katsan
 
How to write clean tests
How to write clean testsHow to write clean tests
How to write clean testsDanylenko Max
 
Advance unittest
Advance unittestAdvance unittest
Advance unittestReza Arbabi
 
Testing javascript in the frontend
Testing javascript in the frontendTesting javascript in the frontend
Testing javascript in the frontendFrederic CABASSUT
 
ASP.NET MVC 3.0 Validation
ASP.NET MVC 3.0 ValidationASP.NET MVC 3.0 Validation
ASP.NET MVC 3.0 ValidationEyal Vardi
 
Testing ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETTesting ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETBen Hall
 
A better approach for testing microservices - introducing test kits in practice
A better approach for testing microservices - introducing test kits in practiceA better approach for testing microservices - introducing test kits in practice
A better approach for testing microservices - introducing test kits in practiceMaxim Novak
 
Sql server ___________session_18(stored procedures)
Sql server  ___________session_18(stored procedures)Sql server  ___________session_18(stored procedures)
Sql server ___________session_18(stored procedures)Ehtisham Ali
 

Ähnlich wie Clean Test Code (20)

The secret unit testing tools no one ever told you about
The secret unit testing tools no one ever told you aboutThe secret unit testing tools no one ever told you about
The secret unit testing tools no one ever told you about
 
1 aleksandr gritsevski - attd example using
1   aleksandr gritsevski - attd example using1   aleksandr gritsevski - attd example using
1 aleksandr gritsevski - attd example using
 
How to write clean tests
How to write clean testsHow to write clean tests
How to write clean tests
 
Clean tests good tests
Clean tests   good testsClean tests   good tests
Clean tests good tests
 
Qtp day 3
Qtp day 3Qtp day 3
Qtp day 3
 
Agile Android
Agile AndroidAgile Android
Agile Android
 
Advance unittest
Advance unittestAdvance unittest
Advance unittest
 
The Art of Test Patterns
The Art of Test PatternsThe Art of Test Patterns
The Art of Test Patterns
 
A Test of Strength
A Test of StrengthA Test of Strength
A Test of Strength
 
Testing javascript in the frontend
Testing javascript in the frontendTesting javascript in the frontend
Testing javascript in the frontend
 
Redux vs Alt
Redux vs AltRedux vs Alt
Redux vs Alt
 
ASP.NET MVC 3.0 Validation
ASP.NET MVC 3.0 ValidationASP.NET MVC 3.0 Validation
ASP.NET MVC 3.0 Validation
 
JavaScript Refactoring
JavaScript RefactoringJavaScript Refactoring
JavaScript Refactoring
 
Testing ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETTesting ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NET
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
A better approach for testing microservices - introducing test kits in practice
A better approach for testing microservices - introducing test kits in practiceA better approach for testing microservices - introducing test kits in practice
A better approach for testing microservices - introducing test kits in practice
 
Sql server ___________session_18(stored procedures)
Sql server  ___________session_18(stored procedures)Sql server  ___________session_18(stored procedures)
Sql server ___________session_18(stored procedures)
 
Agile mobile
Agile mobileAgile mobile
Agile mobile
 
Apex Unit Testing in the Real World
Apex Unit Testing in the Real WorldApex Unit Testing in the Real World
Apex Unit Testing in the Real World
 
Nativescript angular
Nativescript angularNativescript angular
Nativescript angular
 

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

tonesoftg
tonesoftgtonesoftg
tonesoftglanshi9
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...chiefasafspells
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...masabamasaba
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationJuha-Pekka Tolvanen
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...masabamasaba
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benonimasabamasaba
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in sowetomasabamasaba
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburgmasabamasaba
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfkalichargn70th171
 

Kürzlich hochgeladen (20)

tonesoftg
tonesoftgtonesoftg
tonesoftg
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 

Clean Test Code

  • 1. David Völkel, @davidvoelkel Clean Test Code Agile Testing Days 11.11.2014
  • 2. 2 @davidvoelkel Dev & Consultant Software Craftsman Test-Driven Development Software Design @softwerkskammer
  • 3. Dirty Test Code technical debt velocity decrease costs latency agile
  • 4. Clean Tests 4 attributes reliable readable redundancy-free focused Conclusion Q&A
  • 5. xUnit- Patterns BDD Functional tests setup arrange given Input rows execute act when “Fixture“ verify assert then Output rows [teardown] [annihilate] Test Phases Input Output
  • 6. Reliable Mind complexity, so avoid •boolean assertions assertTrue(age >= 18); assertThat(age, greaterThan(17))
  • 7. Reliable Mind complexity, so avoid •boolean assertions •conditionals & complex loops boolean containsName = false; for (String name: names) { if (name.equals("David")) { containsName = true; } } assertTrue(containsName); assertThat(names, hasItem("David"));
  • 8. Readable Read >> write Executable specifications Living documentation
  • 10. Test Method Body 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! “
  • 11. “In the order form the user should be able to finish the order process by pressing the cancel button”
  • 12. @Test public void cancelProcess_inOrderForm() { server.runningProcesses(0); ProcessStatus process = server.startProcess(Process.ORDER); processInstanceId = process.getInstanceId(); server.runningProcesses(1); server.expectUserForm(processInstanceId, ORDER_FORM); Form form = new Form(); form.setOrderDate("01.01.2015"); form.setStandardDelivery(false); String taskId = server.taskIdFor(processInstanceId); controller.submit(form, Mockito.mock(BindingResult.class), null, taskId, null, CANCEL); server.runningProcesses(0); } “In the order form the user should be able to finish the order process by pressing the cancel button”
  • 13. @Test public void cancelProcess_inOrderForm() { server.runningProcesses(0); ProcessStatus process = server.startProcess(Process.ORDER); processInstanceId = process.getInstanceId(); server.runningProcesses(1); server.expectUserForm(processInstanceId, ORDER_FORM); Form form = new Form(); form.setOrderDate("01.01.2015"); form.setStandardDelivery(false); String taskId = server.taskIdFor(processInstanceId); controller.submit(form, Mockito.mock(BindingResult.class), null, taskId, null, CANCEL); server.runningProcesses(0); } “In the order form the user should be able to finish the order process by pressing the cancel button” „Testscript“ “Incidental Details”
  • 14. @Test public void cancelProcess_inOrderForm() { server.runningProcesses(0); ProcessStatus process = server.stareProcess(Process.ORDER); processInstanceId = process.getInstanceId(); server.runningProcesses(1); server.expectUserForm(processInstanceId, ORDER_FORM); Form form = new Form(); form.setOrderDate("01.01.2015"); form.setStandardDelivery(false); String taskId = server.taskIdFor(processInstanceId); controller.submit(form, Mockito.mock(BindingResult.class), null, taskId, null, CANCEL); server.runningProcesses(0); } FORM CANCEL Signal-Noise-Ratio? Single Level of Abstraction? “In the order form the user should be able to finish the order process by pressing the cancel button”
  • 15. @Test public void cancelProcess_inOrderForm() { inForm(ORDER_FORM); submitFormWithButton(CANCEL); noProcessRunning(); } “In the order form the user should be able to finish the order process by pressing the cancel button”
  • 16. Names
  • 17. Test class names public class AnOrderProcess { OrderProcess process; @Before public void createOrderProcess() { process = new OrderProcess(); } object under test
  • 18. 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)); } Test method names object under test
  • 19. 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)); } Test method names object under test setup
  • 20. @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)); } Test method names setup execute
  • 21. @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)); } Test method names setup execute verify
  • 22. Audience? test maintainer search test failure cause business
  • 23. Communicate comprehensively OuT + setup + execute + verify Distribute: Class, method name, verify
  • 25. Hierarchical 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)); } } … extract common setup
  • 26. OuT Hierarchical tests setup execute verify
  • 27. Helper methods 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(); Common test data
  • 28. 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")); } Custom asserts via helper methods Composed Hamcrest Matchers Common verify
  • 29. "Single Concept per Test" "One Execute per Test" "One Assert per Test" Focused
  • 31. „Listen to your tests!“ Hard-to-test Code
  • 32. Clean Tests 1.reliable 2.readable 3.redundancy-free 4.focussed
  • 33. Clean Test Code, stay agile!
  • 34. Resources Books „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 Episodes 20-22 http://cleancoders.com/, Robert C. Martin
  • 35. David Völkel codecentric AG Twitter: @davidvoelkel david.voelkel@codecentric.de www.codecentric.de blog.codecentric.de Q&A 35
  • 36. Creative Commons ShareAlike 4.0 The images used are public domain and can be found on Wikipedia. License 36