SlideShare a Scribd company logo
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

More Related Content

RTF
Easy Button
PDF
Developer Test - Things to Know
KEY
SOLID Principles
PDF
KEY
Taking a Test Drive
PDF
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
PDF
Understanding JavaScript Testing
PDF
Form認証で学ぶSpring Security入門
Easy Button
Developer Test - Things to Know
SOLID Principles
Taking a Test Drive
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Understanding JavaScript Testing
Form認証で学ぶSpring Security入門

What's hot (20)

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

Viewers also liked (11)

PDF
Wann soll ich mocken?
PDF
Mockist vs. Classicists TDD
PDF
Transformation Priority Premise @Softwerkskammer MUC
PDF
Clean Test Code (Clean Code Days)
PDF
Wie wird mein Code testbar?
PDF
Mockist vs. Classicists TDD
PDF
Baby Steps TDD Approaches
PDF
Unit vs. Integration Tests
PDF
Mockist vs Classicists TDD
PDF
Integration Test Hell
PDF
Bad test, good test
Wann soll ich mocken?
Mockist vs. Classicists TDD
Transformation Priority Premise @Softwerkskammer MUC
Clean Test Code (Clean Code Days)
Wie wird mein Code testbar?
Mockist vs. Classicists TDD
Baby Steps TDD Approaches
Unit vs. Integration Tests
Mockist vs Classicists TDD
Integration Test Hell
Bad test, good test
Ad

Similar to Clean Test Code (20)

PDF
The Evolution of Development Testing
PPTX
Principles and patterns for test driven development
PDF
Not your father's tests
PDF
Testing Java Code Effectively
PDF
Better Testing Through Behaviour
PPTX
DotNet unit testing training
PDF
Unit testing basic
PDF
TDD step patterns
PDF
Testing Java Code Effectively - BaselOne17
PDF
An Introduction To Unit Testing and TDD
PPTX
Tdd & unit test
PDF
Android Test Driven Development & Android Unit Testing
PPTX
JUnit Test Case With Processminer modules.pptx
PPTX
TDD - Unit Testing
PPTX
The relationship between test and production code quality (@ SIG)
PPTX
Java Unit Testing
PPT
Solit 2012, TDD и отдельные аспекты тестирования в Java, Антонина Шафранская
PDF
2013 DevFest Vienna - Bad Tests, Good Tests
PPT
types of testing with descriptions and examples
PPTX
Java Unit Test - JUnit
The Evolution of Development Testing
Principles and patterns for test driven development
Not your father's tests
Testing Java Code Effectively
Better Testing Through Behaviour
DotNet unit testing training
Unit testing basic
TDD step patterns
Testing Java Code Effectively - BaselOne17
An Introduction To Unit Testing and TDD
Tdd & unit test
Android Test Driven Development & Android Unit Testing
JUnit Test Case With Processminer modules.pptx
TDD - Unit Testing
The relationship between test and production code quality (@ SIG)
Java Unit Testing
Solit 2012, TDD и отдельные аспекты тестирования в Java, Антонина Шафранская
2013 DevFest Vienna - Bad Tests, Good Tests
types of testing with descriptions and examples
Java Unit Test - JUnit

More from David Völkel (12)

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

Recently uploaded (20)

PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PPTX
ai tools demonstartion for schools and inter college
PDF
top salesforce developer skills in 2025.pdf
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
AI in Product Development-omnex systems
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PPTX
CHAPTER 2 - PM Management and IT Context
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PPTX
Transform Your Business with a Software ERP System
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PPTX
history of c programming in notes for students .pptx
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Softaken Excel to vCard Converter Software.pdf
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
How to Choose the Right IT Partner for Your Business in Malaysia
How to Migrate SBCGlobal Email to Yahoo Easily
ai tools demonstartion for schools and inter college
top salesforce developer skills in 2025.pdf
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
AI in Product Development-omnex systems
Wondershare Filmora 15 Crack With Activation Key [2025
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
CHAPTER 2 - PM Management and IT Context
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Odoo POS Development Services by CandidRoot Solutions
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Transform Your Business with a Software ERP System
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
Design an Analysis of Algorithms I-SECS-1021-03
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
history of c programming in notes for students .pptx
Raksha Bandhan Grocery Pricing Trends in India 2025.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