Upgrade to Pro — share decks privately, control downloads, hide ads and more …

BDD Bialystok/Wroclaw

BDD Bialystok/Wroclaw

Presentation on BDD, architecture and testable code I've given at Mobile Bialystok in December 2016 and at LET Swift Wroclaw in January 2017.

Pawel Dudek

January 19, 2017
Tweet

More Decks by Pawel Dudek

Other Decks in Programming

Transcript

  1. Behavior Driven
    Development

    View Slide

  2. View Slide

  3. View Slide

  4. View Slide

  5. View Slide

  6. Behavior Driven
    Development
    6

    View Slide

  7. What is a unit test?
    @eldudi 7

    View Slide

  8. A method by which individual units of
    source code, sets of one or more program
    modules together with associated control
    data, usage procedures, and operating
    procedures are tested to determine if they
    are fit for use.
    --Kolawa, Adam; Huizinga, Dorota (2007)
    @eldudi 8

    View Slide

  9. Um, what?
    @eldudi 9

    View Slide

  10. A method by which individual units of
    source code, sets of one or more program
    modules together with associated control
    data, usage procedures, and operating
    procedures are tested to determine if they
    are fit for use.
    --Kolawa, Adam; Huizinga, Dorota (2007)
    @eldudi 10

    View Slide

  11. What is an app?
    @eldudi 11

    View Slide

  12. An app is a set of
    behaviors created by
    programmer and
    expected by user.
    @eldudi 12

    View Slide

  13. We, programmers,
    have a limited
    cognition. As all
    humans do.
    @eldudi 13

    View Slide

  14. We can’t always ‘load’
    all of the code of our
    app into our memory.
    @eldudi 14

    View Slide

  15. This means that we
    can, by accident,
    change the behavior of
    the app.
    @eldudi 15

    View Slide

  16. Preserving behavior of
    complex systems is
    hard. In fact, of any
    system at all.
    @eldudi 16

    View Slide

  17. Enter unit tests.
    @eldudi 17

    View Slide

  18. Unit test is a failsafe
    to make sure app
    behavior is preserved.
    @eldudi 18

    View Slide

  19. Test Driven
    Development
    @eldudi 19

    View Slide

  20. Tests drive the way you
    code
    @eldudi 20

    View Slide

  21. Always write test first
    @eldudi 21

    View Slide

  22. Tests influence
    architecture of your
    app
    @eldudi 22

    View Slide

  23. Tests tell you whether
    your design became
    too complex
    @eldudi 23

    View Slide

  24. There is no such thing
    as untestable behavior
    Only untestable code
    @eldudi 24

    View Slide

  25. Have to simulate
    behavior of your
    dependency
    dependency
    dependency?
    @eldudi 25

    View Slide

  26. Need to fake seven
    objects?
    @eldudi 26

    View Slide

  27. Need to call five
    functions to simulate
    a behavior?
    @eldudi 27

    View Slide

  28. Hard to specify clear
    requirements?
    @eldudi 28

    View Slide

  29. Overcomplicated
    design
    @eldudi 29

    View Slide

  30. Thinked-through
    design
    @eldudi 30

    View Slide

  31. First consumer of your
    API
    @eldudi 31

    View Slide

  32. There is no such thing
    as untestable behavior
    Only untestable code
    @eldudi 32

    View Slide

  33. What is testable code?
    @eldudi 33

    View Slide

  34. Testable code
    ==
    Good Architecture
    @eldudi 34

    View Slide

  35. What is good
    architecture?
    @eldudi 35

    View Slide

  36. Cohesion
    @eldudi 36

    View Slide

  37. Coupling
    @eldudi 37

    View Slide

  38. Good design
    A simple definition
    @eldudi 38

    View Slide

  39. Good design
    » High cohesion
    » Low coupling
    » Easily composable
    » Context independent
    @eldudi 39

    View Slide

  40. Good architecture - principles
    » Single responsibility
    » Few dependencies
    » Depend on interfaces, not classes (yay POP!)
    @eldudi 40

    View Slide

  41. @eldudi 41

    View Slide

  42. !!!
    @eldudi 42

    View Slide

  43. http://www.martinfowler.com/
    bliki/
    DesignStaminaHypothesis.html
    @eldudi 43

    View Slide

  44. SOLID
    @eldudi 44

    View Slide

  45. SOLID
    Homework
    » Goruco 2009 - SOLID Object-Oriented Design - Sandi Metz
    » MCE^3 - Software Paradigms & Patterns — Did We Get It All
    Wrong? - Jon Reid
    » MCE^3 - Jorge Ortiz
    » Clean Architecture - Uncle Bob
    @eldudi 45

    View Slide

  46. What is BDD
    @eldudi 46

    View Slide

  47. Behavior Driven Development
    Test Driven Development
    @eldudi 47

    View Slide

  48. What's the difference?
    @eldudi 48

    View Slide

  49. BDD aims to improve
    certain aspect of TDD
    @eldudi 49

    View Slide

  50. BDD tries to help you
    know what to test
    @eldudi 50

    View Slide

  51. When writing tests
    don’t think ‘tests’
    @eldudi 51

    View Slide

  52. Think about
    ‘behaviors’
    @eldudi 52

    View Slide

  53. Think about examples
    how your object
    should behave
    @eldudi 53

    View Slide

  54. An objects behavior is
    defined by methods it
    declares in its
    interface
    @eldudi 54

    View Slide

  55. You should not be testing internal
    implementation of your object
    Only its interface
    @eldudi 55

    View Slide

  56. Work outside-in
    @eldudi 56

    View Slide

  57. Ubiquitous language
    @eldudi 57

    View Slide

  58. Quick & Nimble
    @eldudi 58

    View Slide

  59. class DolphinSpec: QuickSpec {
    override func spec() {
    it("is friendly") {
    expect(Dolphin().isFriendly).to(beTruthy())
    }
    it("is smart") {
    expect(Dolphin().isSmart).to(beTruthy())
    }
    }
    }
    @eldudi 59

    View Slide

  60. describe("a dolphin") {
    describe("its click") {
    it("is loud") {
    let click = Dolphin().click()
    expect(click.isLoud).to(beTruthy())
    }
    it("has a high frequency") {
    let click = Dolphin().click()
    expect(click.hasHighFrequency).to(beTruthy())
    }
    }
    }
    @eldudi 60

    View Slide

  61. describe("a dolphin") {
    var dolphin: Dolphin!
    beforeEach { dolphin = Dolphin() }
    describe("its click") {
    var click: Click!
    beforeEach { click = dolphin.click() }
    it("is loud") {
    expect(click.isLoud).to(beTruthy())
    }
    it("has a high frequency") {
    expect(click.hasHighFrequency).to(beTruthy())
    }
    }
    }
    @eldudi 61

    View Slide

  62. describe("its click") {
    context("when the dolphin is not near anything interesting") {
    it("is only emitted once") {
    expect(dolphin!.click().count).to(equal(1))
    }
    }
    context("when the dolphin is near something interesting") {
    beforeEach {
    let ship = SunkenShip()
    Jamaica.dolphinCove.add(ship)
    Jamaica.dolphinCove.add(dolphin)
    }
    it("is emitted three times") {
    expect(dolphin.click().count).to(equal(3))
    }
    }
    }
    @eldudi 62

    View Slide

  63. Example
    @eldudi 63

    View Slide

  64. BDD - recap
    » Tests influence your architecture
    » No such thing as untestable behavior
    » Think examples/behaviors, not tests
    » Don’t test implementation, work outside-in
    » Use ubiquitous language to make examples easily
    understandable
    @eldudi 64

    View Slide

  65. Further read:
    » objc.io/issue-15
    » github.com/paweldudek/good-tdd-stuff
    Getting in touch:
    » @eldudi
    » [email protected]
    @eldudi 65

    View Slide