FAKE IT OUTSIDE-IN TDD
David Völkel
24th May @ XP 2017
@DAVIDVOELKEL
@codecentric
@softwerkskammer
#TDD
INFLUENCES
2003 Kent Beck’s "Fake It" Pattern
2009 #GOOS’s "Outside-In" Design
2013 Emily Bache 

"Outside-In development with Double Loop TDD"
2014 Justin Searls "The Failures of 'Intro to TDD'"
COMBINATION
2015 Dimitry Polivaev Outside-In with faked Data
2016 SoCraTes DE Outside-In Fake It Session
2017 Refinement
INFLUENCES
2003 Kent Beck’s "Fake It" Pattern
2009 #GOOS’s "Outside-In" Design
2013 Emily Bache 

"Outside-In development with Double Loop TDD"
2014 Justin Searls "The Failures of 'Intro to TDD'"
COMBINATION
2015 Dimitry Polivaev Outside-In with faked Data
2016 SoCraTes DE Outside-In Fake It Session
2017 Refinement
INFLUENCES
2003 Kent Beck’s "Fake It" Pattern
2009 #GOOS’s "Outside-In" Design
COMBINATION
FAKE IT OUTSIDE-IN TDD
INFLUENCES
2003 Kent Beck’s "Fake It" Pattern
2009 #GOOS’s "Outside-In" Design
2013 Emily Bache 

"Outside-In development with Double Loop TDD"
2014 Justin Searls "The Failures of 'Intro to TDD'"
COMBINATION
2016 SoCraTes DE Outside-In Fake It Session
INFLUENCES
2003 Kent Beck’s "Fake It" Pattern
2009 #GOOS’s "Outside-In" Design
2013 Emily Bache 

"Outside-In development with Double Loop TDD"
2014 Justin Searls "The Failures of 'Intro to TDD'"
COMBINATION
2016 SoCraTes DE Outside-In Fake It Session
2017 Refinement / Work in Progress
INFLUENCES
2003 Kent Beck’s "Fake It" Pattern
2009 #GOOS’s "Outside-In" Design
2013 Emily Bache 

"Outside-In development with Double Loop TDD"
COMBINATION
2016 SoCraTes DE Outside-In Fake It Session
2017 Refinement / Work in Progress
INFLUENCES
2003 Kent Beck’s "Fake It" Pattern
2009 #GOOS’s "Outside-In" Design
2013 Emily Bache 

"Outside-In development with Double Loop TDD"
2014 Justin Searls "The Failures of 'Intro to TDD'"
COMBINATION
2016 SoCraTes DE Outside-In Fake It Session
2017 Refinement / Work in Progress
INFLUENCES
2003 Kent Beck’s "Fake It" Pattern
2009 #GOOS’s "Outside-In" Design
2013 Emily Bache 

"Outside-In development with Double Loop TDD"
2014 Justin Searls "The Failures of 'Intro to TDD'"
2017 Llewelyn Falco „Extreme: Fake it Till you Make It“
COMBINATION
2016 SoCraTes DE Outside-In Fake It Session
2017 Refinement / Work in Progress
AGENDA
Theory
Building Blocks
Fake It Outside-In
Practice
Mob Programming Session
Reflect
Trade-Offs
Discussion
BUILDING BLOCKS
INTEGRATION OPERATION
SEGREGATION PRINCIPLE
*"Integration Operation Segregation Principle", Ralf Westphal
"Die kniffligen Fälle beim Testen - Sichtbarkeit", Stefan Lieser
*
INTEGRATION OPERATION
SEGREGATION PRINCIPLE
public void sendDiscountMailingTo(String email) {
Customer customer = customerDB.findCustomerBy(email);
Account account = customer.account();
String discount = account == FREE ? "no" :
account == BASE ? "a 10%" :
account == PREMIUM ? "a 25%" :
"-ERROR-";
String content = "Hello " + customer.getName() + ",nn" +
"This week you get " + discount + " discount " +
"on all our products.nn" +
"Best Regards,n" + "ACME Customer Service";
mailService.sendMail(email, content);
}
OPERATION
public void sendDiscountMailingTo(String email) {
Customer customer = customerDB.findCustomerBy(email);
Account account = customer.account();
String discount = account == FREE ? "no" :
account == BASE ? "a 10%" :
account == PREMIUM ? "a 25%" :
"-ERROR-";
String content = "Hello " + customer.getName() + ",nn" +
"This week you get " + discount + " discount " +
"on all our products.nn" +
"Best Regards,n" + "ACME Customer Service";
mailService.sendMail(email, content);
}
INTEGRATION OPERATION
SEGREGATION PRINCIPLE
INTEGRATION
INTEGRATION
OPERATION
public void sendDiscountMailingTo(String email) {
Customer customer = customerDB.findCustomerBy(email);
Account account = customer.account();
String discount = account == FREE ? "no" :
account == BASE ? "a 10%" :
account == PREMIUM ? "a 25%" :
"-ERROR-";
String content = "Hello " + customer.getName() + ",nn" +
"This week you get " + discount + " discount " +
"on all our products.nn" +
"Best Regards,n" + "ACME Customer Service";
mailService.sendMail(email, content);
}
INTEGRATION OPERATION
SEGREGATION PRINCIPLE
INTEGRATION
INTEGRATION
OPERATION
public void sendDiscountMailingTo(String email) {
Customer customer = customerDB.findCustomerBy(email);
Account account = customer.account();
String discount = account == FREE ? "no" :
account == BASE ? "a 10%" :
account == PREMIUM ? "a 25%" :
"-ERROR-";
String content = "Hello " + customer.getName() + ",nn" +
"This week you get " + discount + " discount " +
"on all our products.nn" +
"Best Regards,n" + "ACME Customer Service";
mailService.sendMail(email, content);
}
INTEGRATION OPERATION
SEGREGATION PRINCIPLE
OPERATION
INTEGRATION
public void sendDiscountMailingTo(String email) {
Customer customer = customerDB.findCustomerBy(email);
String content = renderMessage(customer, customer.account());
mailService.sendMail(email, content);
}
private String renderMessage(Customer customer, Account account) {
String discount = account == FREE ? "no" :
account == BASE ? "a 10%" :
account == PREMIUM ? "a 25%" :
"-ERROR-";
return "Hello " + customer.getName() + ",nn" +
"This week you get " + discount + " discount " +
"on all our products.nn" +
"Best Regards,n" + "ACME Customer Service";
}
INTEGRATION OPERATION
SEGREGATION PRINCIPLE
public void sendDiscountMailingTo(String email) {
Customer customer = customerDB.findCustomerBy(email);
String content = renderMessage(customer, customer.account());
mailService.sendMail(email, content);
}
private String renderMessage(Customer customer, Account account) {
String discount = account == FREE ? "no" :
account == BASE ? "a 10%" :
account == PREMIUM ? "a 25%" :
"-ERROR-";
return "Hello " + customer.getName() + ",nn" +
"This week you get " + discount + " discount " +
"on all our products.nn" +
"Best Regards,n" + "ACME Customer Service";
}
TESTS?
OPERATION
public void sendDiscountMailingTo(String email) {
Customer customer = customerDB.findCustomerBy(email);
String content = renderMessage(customer, customer.account());
mailService.sendMail(email, content);
}
private String renderMessage(Customer customer, Account account) {
String discount = account == FREE ? "no" :
account == BASE ? "a 10%" :
account == PREMIUM ? "a 25%" :
"-ERROR-";
return "Hello " + customer.getName() + ",nn" +
"This week you get " + discount + " discount " +
"on all our products.nn" +
"Best Regards,n" + "ACME Customer Service";
}
TESTS?
N UNITTESTS
INTEGRATION
OPERATION
public void sendDiscountMailingTo(String email) {
Customer customer = customerDB.findCustomerBy(email);
String content = renderMessage(customer, customer.account());
mailService.sendMail(email, content);
}
private String renderMessage(Customer customer, Account account) {
String discount = account == FREE ? "no" :
account == BASE ? "a 10%" :
account == PREMIUM ? "a 25%" :
"-ERROR-";
return "Hello " + customer.getName() + ",nn" +
"This week you get " + discount + " discount " +
"on all our products.nn" +
"Best Regards,n" + "ACME Customer Service";
}
TESTS?1 INTEGRATION TEST
N UNITTESTS
GREEN BAR PATTERNS*
Obvious Implementation
Fake it (until you make it)
Triangulation
* Kent Beck in "TDD by Example"
GREEN BAR PATTERNS
Obvious Implementation
Fake it
Triangulation
Trade-Off
Complexity
GREEN BAR PATTERNS
DEMO
SWEET SPOT
Logic
GREEN BAR PATTERNS
Obvious Implementation
Fake it
Triangulation
SWEET SPOT
Structure
Logic
GREEN BAR PATTERNS
Obvious Implementation
Fake it
Triangulation
SWEET SPOT
Trivial
Structure
Logic
GREEN BAR PATTERNS
Obvious Implementation
Fake it
Triangulation
INTEGRATION
OPERATION
Fake it
Triangulation
GREEN BAR PATTERNS
Structure
Logic
IOSP
PREPARATORY REFACTORINGS*
*"An example of preparatory refactoring", Martin Fowler
"GREEN" PHASE TRIANGULATION
Implementation Run Test
"Green Phase"
LIMIT YOUR TIME IN RED
"Green Phase"
Implementation Run Test
Implementation Run TestPreparatory Refactoring
PREPARATORY REFACTORINGS
DEMO
Acceptance Test
UI
Persistence
OUTSIDE-IN
Unit test
Mock
OUTSIDE-IN & MOCKS
Unit Test
OUTSIDE-IN & MOCKS
Acceptance Test
UI
Persistence
OUTSIDE-IN & MOCKS
Comprehensive
Acceptance Test
OUTSIDE-IN & FAKE IT
Comprehensive
Acceptance Test
Faked Result
OUTSIDE-IN & FAKE IT
Acceptance Test
Fake
Fake
OUTSIDE-IN & FAKE IT
Acceptance Test Drive Structure
through Refactoring
OUTSIDE-IN & FAKE IT
OUTSIDE-IN & FAKE IT
Acceptance Test
Unit Test
Fill logic with
triangulation
OUTSIDE-IN & FAKE IT
Acceptance Test Unit Test
OUTSIDE-IN & FAKE IT
INTEGRATION
Fake It
Triangulation
OPERATION
Start with
• comprehensive 

Acceptance Test
• faked result
Drive structure by refactoring
Drive logic by unit tests
OUTSIDE-IN & FAKE IT
INTEGRATION
Fake It
Triangulation
OPERATION
Start with
• comprehensive 

Acceptance Test
• faked result
Drive structure by refactoring
Drive logic by unit tests
DIAMOND KATA
FAKE IT OUTSIDE-IN
DEMO
FAKE-IT VARIANT
CALCULATE BACKWARDS
DEMO
PRACTICE
CODING SESSION
KATA
Continue Diamond Kata
https://github.com/davidvoelkel/diamond-kata
CONSTRAINTS
Drive structure by refactoring
Drive conditionals by triangulation
TRADE-OFFS
FAKE IT VS
OUTSIDE-IN & MOCKS
TRIANGULATION
CONDITIONAL INTERACTIONS
Mocking when IOSP not possible
public String signup(String username) throws Exception {
if(userDB.findUserBy(username) == null) {
userDB.createUser(new User(username));
return "Welcome " + username;
} else {
return "Username ' " + username + "' "
+ "already taken, please choose another";
}
}
COUPLING OUTSIDE-IN
Mocking Fake It
Decoupling Refactorability
DATA GUIDES STRUCTURE
Triangulation Fake It
Structure Cumbersome Data guides well
# BRANCHES
Triangulation Fake It
# N 1
More confidence
More effort
# BRANCHES
Triangulation Fake It
# N 1
Fake data easy to forget
Omitting cases is
tempting
TIME IN GREEN
Triangulation
Prep Refactoring
Triangulation
Fake It
DISCUSSION
LICENSE
Creative Commons Attribution-ShareAlike 3.0
IMAGES
Most are Public Domain except theses
Creative Commons with attributions:
"Unstruttalbrücke" by Störfix
From State Library of Queensland

Fake It Outside-In TDD @XP2017

  • 1.
    FAKE IT OUTSIDE-INTDD David Völkel 24th May @ XP 2017
  • 2.
  • 3.
    INFLUENCES 2003 Kent Beck’s"Fake It" Pattern 2009 #GOOS’s "Outside-In" Design 2013 Emily Bache 
 "Outside-In development with Double Loop TDD" 2014 Justin Searls "The Failures of 'Intro to TDD'" COMBINATION 2015 Dimitry Polivaev Outside-In with faked Data 2016 SoCraTes DE Outside-In Fake It Session 2017 Refinement
  • 4.
    INFLUENCES 2003 Kent Beck’s"Fake It" Pattern 2009 #GOOS’s "Outside-In" Design 2013 Emily Bache 
 "Outside-In development with Double Loop TDD" 2014 Justin Searls "The Failures of 'Intro to TDD'" COMBINATION 2015 Dimitry Polivaev Outside-In with faked Data 2016 SoCraTes DE Outside-In Fake It Session 2017 Refinement
  • 5.
    INFLUENCES 2003 Kent Beck’s"Fake It" Pattern 2009 #GOOS’s "Outside-In" Design COMBINATION FAKE IT OUTSIDE-IN TDD
  • 6.
    INFLUENCES 2003 Kent Beck’s"Fake It" Pattern 2009 #GOOS’s "Outside-In" Design 2013 Emily Bache 
 "Outside-In development with Double Loop TDD" 2014 Justin Searls "The Failures of 'Intro to TDD'" COMBINATION 2016 SoCraTes DE Outside-In Fake It Session
  • 7.
    INFLUENCES 2003 Kent Beck’s"Fake It" Pattern 2009 #GOOS’s "Outside-In" Design 2013 Emily Bache 
 "Outside-In development with Double Loop TDD" 2014 Justin Searls "The Failures of 'Intro to TDD'" COMBINATION 2016 SoCraTes DE Outside-In Fake It Session 2017 Refinement / Work in Progress
  • 8.
    INFLUENCES 2003 Kent Beck’s"Fake It" Pattern 2009 #GOOS’s "Outside-In" Design 2013 Emily Bache 
 "Outside-In development with Double Loop TDD" COMBINATION 2016 SoCraTes DE Outside-In Fake It Session 2017 Refinement / Work in Progress
  • 9.
    INFLUENCES 2003 Kent Beck’s"Fake It" Pattern 2009 #GOOS’s "Outside-In" Design 2013 Emily Bache 
 "Outside-In development with Double Loop TDD" 2014 Justin Searls "The Failures of 'Intro to TDD'" COMBINATION 2016 SoCraTes DE Outside-In Fake It Session 2017 Refinement / Work in Progress
  • 10.
    INFLUENCES 2003 Kent Beck’s"Fake It" Pattern 2009 #GOOS’s "Outside-In" Design 2013 Emily Bache 
 "Outside-In development with Double Loop TDD" 2014 Justin Searls "The Failures of 'Intro to TDD'" 2017 Llewelyn Falco „Extreme: Fake it Till you Make It“ COMBINATION 2016 SoCraTes DE Outside-In Fake It Session 2017 Refinement / Work in Progress
  • 11.
    AGENDA Theory Building Blocks Fake ItOutside-In Practice Mob Programming Session Reflect Trade-Offs Discussion
  • 12.
  • 13.
    INTEGRATION OPERATION SEGREGATION PRINCIPLE *"IntegrationOperation Segregation Principle", Ralf Westphal "Die kniffligen Fälle beim Testen - Sichtbarkeit", Stefan Lieser *
  • 14.
    INTEGRATION OPERATION SEGREGATION PRINCIPLE publicvoid sendDiscountMailingTo(String email) { Customer customer = customerDB.findCustomerBy(email); Account account = customer.account(); String discount = account == FREE ? "no" : account == BASE ? "a 10%" : account == PREMIUM ? "a 25%" : "-ERROR-"; String content = "Hello " + customer.getName() + ",nn" + "This week you get " + discount + " discount " + "on all our products.nn" + "Best Regards,n" + "ACME Customer Service"; mailService.sendMail(email, content); }
  • 15.
    OPERATION public void sendDiscountMailingTo(Stringemail) { Customer customer = customerDB.findCustomerBy(email); Account account = customer.account(); String discount = account == FREE ? "no" : account == BASE ? "a 10%" : account == PREMIUM ? "a 25%" : "-ERROR-"; String content = "Hello " + customer.getName() + ",nn" + "This week you get " + discount + " discount " + "on all our products.nn" + "Best Regards,n" + "ACME Customer Service"; mailService.sendMail(email, content); } INTEGRATION OPERATION SEGREGATION PRINCIPLE
  • 16.
    INTEGRATION INTEGRATION OPERATION public void sendDiscountMailingTo(Stringemail) { Customer customer = customerDB.findCustomerBy(email); Account account = customer.account(); String discount = account == FREE ? "no" : account == BASE ? "a 10%" : account == PREMIUM ? "a 25%" : "-ERROR-"; String content = "Hello " + customer.getName() + ",nn" + "This week you get " + discount + " discount " + "on all our products.nn" + "Best Regards,n" + "ACME Customer Service"; mailService.sendMail(email, content); } INTEGRATION OPERATION SEGREGATION PRINCIPLE
  • 17.
    INTEGRATION INTEGRATION OPERATION public void sendDiscountMailingTo(Stringemail) { Customer customer = customerDB.findCustomerBy(email); Account account = customer.account(); String discount = account == FREE ? "no" : account == BASE ? "a 10%" : account == PREMIUM ? "a 25%" : "-ERROR-"; String content = "Hello " + customer.getName() + ",nn" + "This week you get " + discount + " discount " + "on all our products.nn" + "Best Regards,n" + "ACME Customer Service"; mailService.sendMail(email, content); } INTEGRATION OPERATION SEGREGATION PRINCIPLE
  • 18.
    OPERATION INTEGRATION public void sendDiscountMailingTo(Stringemail) { Customer customer = customerDB.findCustomerBy(email); String content = renderMessage(customer, customer.account()); mailService.sendMail(email, content); } private String renderMessage(Customer customer, Account account) { String discount = account == FREE ? "no" : account == BASE ? "a 10%" : account == PREMIUM ? "a 25%" : "-ERROR-"; return "Hello " + customer.getName() + ",nn" + "This week you get " + discount + " discount " + "on all our products.nn" + "Best Regards,n" + "ACME Customer Service"; } INTEGRATION OPERATION SEGREGATION PRINCIPLE
  • 19.
    public void sendDiscountMailingTo(Stringemail) { Customer customer = customerDB.findCustomerBy(email); String content = renderMessage(customer, customer.account()); mailService.sendMail(email, content); } private String renderMessage(Customer customer, Account account) { String discount = account == FREE ? "no" : account == BASE ? "a 10%" : account == PREMIUM ? "a 25%" : "-ERROR-"; return "Hello " + customer.getName() + ",nn" + "This week you get " + discount + " discount " + "on all our products.nn" + "Best Regards,n" + "ACME Customer Service"; } TESTS?
  • 20.
    OPERATION public void sendDiscountMailingTo(Stringemail) { Customer customer = customerDB.findCustomerBy(email); String content = renderMessage(customer, customer.account()); mailService.sendMail(email, content); } private String renderMessage(Customer customer, Account account) { String discount = account == FREE ? "no" : account == BASE ? "a 10%" : account == PREMIUM ? "a 25%" : "-ERROR-"; return "Hello " + customer.getName() + ",nn" + "This week you get " + discount + " discount " + "on all our products.nn" + "Best Regards,n" + "ACME Customer Service"; } TESTS? N UNITTESTS
  • 21.
    INTEGRATION OPERATION public void sendDiscountMailingTo(Stringemail) { Customer customer = customerDB.findCustomerBy(email); String content = renderMessage(customer, customer.account()); mailService.sendMail(email, content); } private String renderMessage(Customer customer, Account account) { String discount = account == FREE ? "no" : account == BASE ? "a 10%" : account == PREMIUM ? "a 25%" : "-ERROR-"; return "Hello " + customer.getName() + ",nn" + "This week you get " + discount + " discount " + "on all our products.nn" + "Best Regards,n" + "ACME Customer Service"; } TESTS?1 INTEGRATION TEST N UNITTESTS
  • 22.
    GREEN BAR PATTERNS* ObviousImplementation Fake it (until you make it) Triangulation * Kent Beck in "TDD by Example"
  • 23.
    GREEN BAR PATTERNS ObviousImplementation Fake it Triangulation Trade-Off Complexity
  • 24.
  • 25.
    SWEET SPOT Logic GREEN BARPATTERNS Obvious Implementation Fake it Triangulation
  • 26.
    SWEET SPOT Structure Logic GREEN BARPATTERNS Obvious Implementation Fake it Triangulation
  • 27.
    SWEET SPOT Trivial Structure Logic GREEN BARPATTERNS Obvious Implementation Fake it Triangulation
  • 28.
  • 29.
    PREPARATORY REFACTORINGS* *"An exampleof preparatory refactoring", Martin Fowler
  • 30.
  • 31.
    LIMIT YOUR TIMEIN RED "Green Phase" Implementation Run Test Implementation Run TestPreparatory Refactoring
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
    Acceptance Test DriveStructure through Refactoring OUTSIDE-IN & FAKE IT
  • 41.
    OUTSIDE-IN & FAKEIT Acceptance Test Unit Test Fill logic with triangulation
  • 42.
    OUTSIDE-IN & FAKEIT Acceptance Test Unit Test
  • 43.
    OUTSIDE-IN & FAKEIT INTEGRATION Fake It Triangulation OPERATION Start with • comprehensive 
 Acceptance Test • faked result Drive structure by refactoring Drive logic by unit tests
  • 44.
    OUTSIDE-IN & FAKEIT INTEGRATION Fake It Triangulation OPERATION Start with • comprehensive 
 Acceptance Test • faked result Drive structure by refactoring Drive logic by unit tests
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
    CODING SESSION KATA Continue DiamondKata https://github.com/davidvoelkel/diamond-kata CONSTRAINTS Drive structure by refactoring Drive conditionals by triangulation
  • 50.
    TRADE-OFFS FAKE IT VS OUTSIDE-IN& MOCKS TRIANGULATION
  • 51.
    CONDITIONAL INTERACTIONS Mocking whenIOSP not possible public String signup(String username) throws Exception { if(userDB.findUserBy(username) == null) { userDB.createUser(new User(username)); return "Welcome " + username; } else { return "Username ' " + username + "' " + "already taken, please choose another"; } }
  • 52.
    COUPLING OUTSIDE-IN Mocking FakeIt Decoupling Refactorability
  • 53.
    DATA GUIDES STRUCTURE TriangulationFake It Structure Cumbersome Data guides well
  • 54.
    # BRANCHES Triangulation FakeIt # N 1 More confidence More effort
  • 55.
    # BRANCHES Triangulation FakeIt # N 1 Fake data easy to forget Omitting cases is tempting
  • 56.
    TIME IN GREEN Triangulation PrepRefactoring Triangulation Fake It
  • 57.
  • 58.
  • 59.
    IMAGES Most are PublicDomain except theses Creative Commons with attributions: "Unstruttalbrücke" by Störfix From State Library of Queensland