Slide 1

Slide 1 text

Test Driven Development Juanjo Coello ([email protected])

Slide 2

Slide 2 text

The Problem Software has unanticipated changes. Always.

Slide 3

Slide 3 text

The Problem Try to write a code which may be easily changed, extended (or dropped).

Slide 4

Slide 4 text

The Problem Can pick only two... FAST GOOD CHEAP

Slide 5

Slide 5 text

LIFE THOU ART UNFAIR!

Slide 6

Slide 6 text

Testing helps to... ● Be a bit faster (in the mid/long term) ● Be a bit cheaper (from minute 0) ● Be a bit better (From minute 0)

Slide 7

Slide 7 text

FASTER

Slide 8

Slide 8 text

Time taken to fix bugs http://www.slideshare.net/Skud/test-driven-development-tutorial

Slide 9

Slide 9 text

CHEAPER

Slide 10

Slide 10 text

Time taken to fix bugs

Slide 11

Slide 11 text

Yes. It's repeated on purpose.

Slide 12

Slide 12 text

● The cost rises because of the technical debt ● "We'll come back to fix this... eventually" ● Testing helps to pay debt regularly. Cheaper

Slide 13

Slide 13 text

BETTER

Slide 14

Slide 14 text

Better ● Testing usually implies less bugs ● Less bugs implies better quality: the software work as expected. ● Not easy to quantify, though.

Slide 15

Slide 15 text

Why do we write automated tests?

Slide 16

Slide 16 text

● Guard against regressions ○ We can add new features without breaking existing ones ● Gain confidence to change Automated Tests:

Slide 17

Slide 17 text

● Frequent manual testing is just impractical ● Reduce the costs of building, deploying, and modifying versions of the system Automated Tests:

Slide 18

Slide 18 text

● Discover better designs ○ We use the tests to clarify our ideas about what we want the code to do. Automated Tests: "When we find a feature that's difficult to test, we don't just ask ourselves how to test it, but also why is it difficult to test." Steve Freeman, Nat Pryce (Growing Object Oriented Software Guided by Tests - GOOS)

Slide 19

Slide 19 text

● Developers spend far more time reading code than writing it, so that’s what we should optimize for. ● Simplicity takes effort. Automated Tests:

Slide 20

Slide 20 text

● Constantly refactor our code as we work with it ○ To improve and simplify its design ○ To remove duplication ○ To ensure that it clearly expresses what it does ● The test suites in the feedback loops protect us against our own mistakes as we improve the code. Automated Tests:

Slide 21

Slide 21 text

Test Driven Development

Slide 22

Slide 22 text

Testing THINK IMPLEMENT TEST

Slide 23

Slide 23 text

TDD THINK TEST IMPLEMENT

Slide 24

Slide 24 text

TDD THINK TEST IMPLEMENT

Slide 25

Slide 25 text

WRITE TEST TEST PASS TEST FAIL WRITE CODE THAT MAKES TEST PASS REFACTOR Feel da flow...

Slide 26

Slide 26 text

"We find that the effort of writing a test first also gives us rapid feedback about the quality of our design ideas - that making code accessible for testing often drives it towards being cleaner and more modular" Steve Freeman, Nat Pryce (GOOS)

Slide 27

Slide 27 text

Example (Groovy rocks)

Slide 28

Slide 28 text

Write once, run often. ● Write tests once ● Run frequently (it should be easy) ● No human input ● Machine-parsable output

Slide 29

Slide 29 text

Bug Fixing

Slide 30

Slide 30 text

Bug Fixing ● Reproduce the error ● Make a test that reproduces the error ○ It should fail ● Fix the bug ○ Now the test should pass ● Keep the test in your Test Suite.

Slide 31

Slide 31 text

Legacy Code

Slide 32

Slide 32 text

"Does anyone know what this does?"

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

"Do you know if there is any documentation related to this?"

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

Legacy Code ● Legacy Code == Technical Debt ● Try to improve it ○ Document it ○ Understand it ○ Clean it up ○ Refactor it

Slide 37

Slide 37 text

WTF!!! TEST PASS TEST FAIL AHMM REFACTOR

Slide 38

Slide 38 text

1. Look at the code. Get scary. 2. Write a first test to see what happens 3. It usually fails 4. Refine it 5. Test passes 6. Grab another piece of code Legacy Code

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

Good Practices

Slide 41

Slide 41 text

S.O.L.I.D. PRINCIPLES ● Single Responsibility ● Open-Closed ● Liskov Substitution ● Interface Segregation ● Dependency Inversion

Slide 42

Slide 42 text

Single Responsibility ● Only one reason to change ○ A single responsibility, and that responsibility entirely encapsulated. 1. "Our heuristic is that we should be able to describe what an object does without using any conjunctions ('and', 'or')" Steve freeman, Nat Pryce (GOOS)

Slide 43

Slide 43 text

Single Responsibility "An element’s cohesion is a measure of whether its responsibilities form a meaningful unit (...) a class that parses both dates and URLs is not coherent, because they are unrelated concepts. Think of a machine that washes both clothes and dishes—it’s unlikely to do both well." Steve freeman, Nat Pryce (GOOS)

Slide 44

Slide 44 text

Single Responsibility "At the other extreme, a class that parses only the punctuation in a URL is unlikely to be coherent, because it does not represent a whole concept. To get anything done, the programmer will have to find other parsers for protocol, host, resource, and so on. Features with “high” coherence are easier to maintain." Steve freeman, Nat Pryce (GOOS)

Slide 45

Slide 45 text

Single Responsibility ● "Methods with no more than 5 lines of code, classes with no more than 3 public methods (average)." Carlos Blé

Slide 46

Slide 46 text

Open-Closed Principle ● Software entities – classes, modules, functions and so on – should be open for extension but closed for modification.

Slide 47

Slide 47 text

Open-Closed Principle ● It’s often better to make changes to things like classes by adding to or building on top of them (using mechanisms like subclassing or polymorphism) rather than modifying their code ● In short: If it works, don't touch it" Carlos Blé

Slide 48

Slide 48 text

Liskov Substitution Principle "If it looks like a duck, swims like a duck, quacks like a duck but it needs batteries, you probably have the wrong abstraction"

Slide 49

Slide 49 text

Liskov Substitution Principle

Slide 50

Slide 50 text

Liskov Substitution Principle ● Subclasses should be substitutable for the classes from which they were derived ● "Don't abuse inheritance (are they really the same thing?)" Carlos Blé

Slide 51

Slide 51 text

● Clients should not be forced to depend on methods they don’t use. ● "This one was placed here to form the word "solid" but it's the same thing" Carlos Blé Interface Segregation Principle

Slide 52

Slide 52 text

● High-level modules should not depend on low-level modules, but both should depend on shared abstractions ● Abstractions should not depend on details – instead, details should depend on abstractions. Dependency Inversion Principle

Slide 53

Slide 53 text

● Basic Idea behind of Inversion of Control (e.g: Spring Framework) ● "Never create the instance of the dependency inside the object which uses it." Carlos Blé Dependency Inversion Principle

Slide 54

Slide 54 text

● DRY (Don't Repeat Yourself) ● KISS (Keep it Simple, Stupid!) ● YAGNI (You ain't gonna need it) Other (Good) Principles

Slide 55

Slide 55 text

Good Principles Online guide: Writing Testable Code http://misko.hevery.com/code-reviewers- guide/ Good Slides: Why our code Smells https://speakerdeck.com/u/bkeepers/p/why-our- code-smells

Slide 56

Slide 56 text

Bibliografy ● Growing Object Oriented Software Guided By Tests ● xUnit Test Patterns ● Refactoring ● Clean Code (awesome) ● Diseño Ágil con TDD (Spanish)

Slide 57

Slide 57 text

Thanks!

Slide 58

Slide 58 text

Let's get our hands dirty!