mockist vs classicists tdd

64
MOCKIST VS CLASSICIST TDD Softwerkskammer Hamburg David Völkel 22.11.2016

Upload: david-voelkel

Post on 15-Jan-2017

152 views

Category:

Software


0 download

TRANSCRIPT

MOCKIST VS CLASSICIST TDD

Softwerkskammer Hamburg

David Völkel

22.11.2016

@davidvoelkel

@softwerkskammer

@codecentric

TDD & Design

CLASSICIST

VS

MOCKIST?

MOCKISTS?

● „London School“: Steve Freeman, Nat Pryce

● XP 2000 paper „Endo-Testing: Unit Testing with Mock Objects “

● OOPSLA 2004 „Mock Roles, not Objects“

● „Growing Object Oriented Software“ #GOOS 2009

MOCKISTS

● Problem Zu viele integrierte Tests => Isoliert testen

● Mocks [& Interfaces]

● Behaviour Verification

● Outside-In Design

MOCKISTS

CLASSICISTS?

“Chicago“ oder “Detroit School“: Kent Beck, Uncle Bob, Ron Jeffries, …

CLASSICISTS

Weniger Mocks,

• nur an Prozessgrenze

• mehr Integrierte Tests

CLASSICISTS

Weniger Mocks,

• nur an Prozessgrenze

• mehr Integrierte Tests

Design

• bottom up vs emergent

CLASSICISTS

DESIGN

DIMENSIONEN

Unsicherheit

Richtung

Isolation

UNSICHERHEIT

Design Dimension

Akzeptanztest

DESIGN UNKLAR?

Akzeptanztest

DESIGN UNKLAR?

Akzeptanztest

DESIGN UNKLAR?

Akzeptanztest

1. Pass the Tests

2. Reveal Intention & No Duplication

3. Fewest Elements

4 RULES OF

SIMPLE DESIGN

"BeckDesignRules", Martin Fowler

Akzeptanztest

1. Pass the Tests

2. Reveal Intention & No Duplication

3. Fewest Elements

4 RULES OF

SIMPLE DESIGN

Akzeptanztest

EMERGENT DESIGN

Akzeptanztest

EMERGENT DESIGN

+ Wenn Design unklar

+ Refaktorierbarkeit

EMERGENT DESIGN

+ Wenn Design unklar

+ Refaktorierbarkeit

- Aufwändig

- Integrierte Tests

EMERGENT DESIGN

RICHTUNG

Design Dimension

Outside-In vs Inside-Out

GUI

Adapter

DRITTSERVICE FIX

3rd Party

Service

Integrations

Test

Adapter

INSIDE-OUT

3rd Party

Service

Test

INSIDE-OUT

3rd Party

Service

Test

GUI / Endpoint

OUTSIDE-IN

Unittest

Mock

OUTSIDE-IN

MOCKING

Test

OUTSIDE-IN

MOCKING

GUI / Endpoint

Akzeptanztest

OUTSIDE-IN

FAKE-IT

Fake

Akzeptanztest

OUTSIDE-IN

FAKE-IT

Fake

Akzeptanztest Fake

OUTSIDE-IN

FAKE-IT

Unittest

Akzeptanztest

OUTSIDE-IN

FAKE-IT

Akzeptanztest

OUTSIDE-IN

FAKE-IT

INSIDE-OUT

Sweetspots

Fixes Drittsystem

Design sehr klar

YAGNI Design Potential!

OUTSIDE-IN

Passgenaues Design

Mocks vs Fake It

ISOLATION

Design Dimension

Mocks vs Integrierte Tests

aufwendiges Setup

Fehlerfindung

# Testfällen

Langsames Feedback

Refactorability sinkt

Isolationsaufwand

Zu wenig Nutzen

Lesbarkeit

TRADE-OFF

ZU GROSS vs ZU KLEIN

OBSOLETES MOCKING

INTEGRATION OPERATION

SEGREGATION PRINCIPLE public void sendMailingTo(String email) {

Customer customer = customerDB.findCustomerBy(email); String title = customer.getSex() == Sex.MALE ? "Mr" : customer.getMaritialStatus() == MaritialStatus.MARRIED ? "Mrs" : "Ms"; String content = "Hello " + title + ". " + customer.getName() + ",\n\n" + "We have a special offer for you.\n\n" + "Best regards,\n" + "ACME Customer Service"; mailService.sendMail(email, content);

}

public void sendMailingTo(String email) {

Customer customer = customerDB.findCustomerBy(email); String title = customer.getSex() == Sex.MALE ? "Mr" : customer.getMaritialStatus() == MaritialStatus.MARRIED ? "Mrs" : "Ms"; String content = "Hello " + title + ". " + customer.getName() + ",\n\n" + "We have a special offer for you.\n\n" + "Best regards,\n" + "ACME Customer Service"; mailService.sendMail(email, content);

}

INTEGRATION OPERATION

SEGREGATION PRINCIPLE

public void sendMailingTo(String email) {

Customer customer = customerDB.findCustomerBy(email); String title = customer.getSex() == Sex.MALE ? "Mr" : customer.getMaritialStatus() == MaritialStatus.MARRIED ? "Mrs" : "Ms"; String content = "Hello " + title + ". " + customer.getName() + ",\n\n" + "We have a special offer for you.\n\n" + "Best regards,\n" + "ACME Customer Service"; mailService.sendMail(email, content);

}

INTEGRATION OPERATION

SEGREGATION PRINCIPLE

public void sendMailingTo(String email) {

Customer customer = customerDB.findCustomerBy(email); String content = renderContent(customer); mailService.sendMail(email, content);

} private String renderContent(Customer customer) {

String title = customer.getSex() == Sex.MALE ? "Mr" : customer.getMaritialStatus() == MaritialStatus.MARRIED ? "Mrs" : "Ms"; return "Hello " + title + ". " + customer.getName() + ",\n\n" + "We have a special offer for you.\n\n" + "Best regards,\n" + "ACME Customer Service";

}

INTEGRATION OPERATION

SEGREGATION PRINCIPLE

public void sendMailingTo(String email) {

Customer customer = customerDB.findCustomerBy(email); String content = renderContent(customer); mailService.sendMail(email, content);

} private String renderContent(Customer customer) {

String title = customer.getSex() == Sex.MALE ? "Mr" : customer.getMaritialStatus() == MaritialStatus.MARRIED ? "Mrs" : "Ms"; return "Hello " + title + ". " + customer.getName() + ",\n\n" + "We have a special offer for you.\n\n" + "Best regards,\n" + "ACME Customer Service";

}

TESTS?

N Unittests

public void sendMailingTo(String email) {

Customer customer = customerDB.findCustomerBy(email); String content = renderContent(customer); mailService.sendMail(email, content);

} private String renderContent(Customer customer) {

String title = customer.getSex() == Sex.MALE ? "Mr" : customer.getMaritialStatus() == MaritialStatus.MARRIED ? "Mrs" : "Ms"; return "Hello " + title + ". " + customer.getName() + ",\n\n" + "We have a special offer for you.\n\n" + "Best regards,\n" + "ACME Customer Service";

}

TESTS? 1 Integrierter Test

N Unittests

PUSH LOGIC

DOWN THE STACK

MOCKING

SWEETSPOTS

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";

} }

BEDINGTE

INTERAKTION

SYSTEM GRENZEN

3rd Party

Service

Adapter

SYSTEM GRENZEN

3rd Party

Service

Mock

DESIGN

DIMENSIONEN

Unsicherheit

Richtung

Isolation

DESIGN

ALGORITHMUS

if (unsicher) Emergent

else if (drittsys) Inside-Out

else if (isoliert) Outside-In Mockist

else Outside-In Fake-It

DESIGN

ALGORITHMUS

if (unsicher) Emergent

else if (drittsys) Inside-Out

else if (isoliert) Outside-In Mockist

else Outside-In Fake-It

DESIGN

ALGORITHMUS

if (unsicher) Emergent

else if (drittsys) Inside-Out

else if (isoliert) Outside-In Mockist

else Outside-In Fake-It

DESIGN

ALGORITHMUS

if (unsicher) Emergent

else if (drittsys) Inside-Out

else if (isoliert) Outside-In Mockist

else Outside-In Fake-It

SCHULEN

if (unsicher) Emergent

else if (drittsys) Inside-Out

else if (isoliert) Outside-In MOCKIST

else Outside-In Fake-It

CLASSICIST

MOCKIST

ODER

CLASSICIST?

TRADE-OFF!

MOCKIST

ODER

CLASSICIST?

KOMBINIEREN!

MOCKIST

ODER

CLASSICIST?

KOMBINIEREN!

TRADE-OFFS!

QUELLEN

• "Growing Object Oriented Systems", Nat Pryce, Steve Freeman

• "Mocks Aren't Stubs", Martin Fowler

• "Integration Operation Segregation Principle", Ralf Westphal

• „Die kniffligen Fälle beim Testen – Sichtbarkeit“, Stefan Lieser

• "The Failures of “Intro to TDD”" Justin Searls

Q&A ?!