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

Poznan TDD Workshop Part 1

Poznan TDD Workshop Part 1

Pawel Dudek

June 18, 2016
Tweet

More Decks by Pawel Dudek

Other Decks in Programming

Transcript

  1. Mobile
    Academy

    View Slide

  2. Mobile
    Academy
    @eldudi
    #TDDPoznan

    View Slide

  3. What is a unit test?
    @eldudi #TDDWarsaw

    View Slide

  4. @eldudi #TDDPoznań
    “Unit testing is a method by which
    individual units of source code, sets of
    one or more computer program
    modules together with associated
    control data, usage procedures, and
    operating procedures are tested to
    determine if they are fit for use.”
    4
    Kolawa, Adam; Huizinga, Dorota (2007). Automated Defect Prevention: Best Practices in
    Software Management.

    View Slide

  5. @eldudi #TDDPoznan
    Um… what?
    5

    View Slide

  6. @eldudi #TDDPoznań
    “Unit testing is a method by which
    individual units of source code, sets of
    one or more computer program
    modules together with associated
    control data, usage procedures, and
    operating procedures are tested to
    determine if they are fit for use.”
    6
    Kolawa, Adam; Huizinga, Dorota (2007). Automated Defect Prevention: Best Practices in
    Software Management.

    View Slide

  7. @eldudi #TDDPoznan
    What is an app?
    7

    View Slide

  8. @eldudi #TDDPoznan
    An app is a set of
    behaviours created by
    programmer and
    expected by user.
    8

    View Slide

  9. @eldudi #TDDPoznan
    We, programmers, have
    a limited cognition. As
    all humans do.
    9

    View Slide

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

    View Slide

  11. @eldudi #TDDPoznan
    This means that we can,
    by accident, change the
    behaviour of the app.
    11

    View Slide

  12. @eldudi #TDDPoznan
    Preserving behaviour of
    complex systems is
    hard. In fact, of any
    system at all.
    12

    View Slide

  13. @eldudi #TDDPoznan
    Enter unit tests.
    13

    View Slide

  14. @eldudi #TDDPoznan
    Unit test is a failsafe to
    make sure app
    behaviour is preserved.
    14

    View Slide

  15. @eldudi #TDDPoznan
    What is a unit test?
    15

    View Slide

  16. @eldudi #TDDPoznan
    Unit tests test smallest
    parts of your code in
    isolation with test code
    16

    View Slide

  17. @eldudi #TDDPoznan
    Unit tests test smallest
    parts of your code in
    isolation with test code
    17

    View Slide

  18. @eldudi #TDDPoznan
    Test isolation
    18

    View Slide

  19. @eldudi #TDDPoznań
    processOrder getDishes
    19
    Table Waiter Cook

    View Slide

  20. @eldudi #TDDPoznań
    I’m
    a cook
    Table Waiter Cook
    processOrder
    getDishes
    Fake cook
    20

    View Slide

  21. @eldudi #TDDPoznan
    Why isolate?
    21

    View Slide

  22. @eldudi #TDDPoznan
    Unit test lifecycle
    22

    View Slide

  23. @eldudi #TDDPoznań
    Unit test lifecycle
    • Arrange
    • Act
    • Assert
    23

    View Slide

  24. @eldudi #TDDPoznan
    When a unit test is not
    a unit test?
    24

    View Slide

  25. @eldudi #TDDPoznań
    A test is not a unit test if…
    • It talks to a database
    • It communicates across network
    • It touches the file system
    • You have to do special things to your environment
    to run it (edit config files etc)
    25

    View Slide

  26. @eldudi #TDDPoznań
    A test is not a unit test if…
    • It talks to a database
    • It communicates across network
    • It touches the file system
    • You have to do special things to your environment
    to run it (edit config files etc)
    26

    View Slide

  27. @eldudi #TDDPoznań
    A test is not a unit test if…
    • It talks to a database
    • It communicates across network
    • It touches the file system
    • You have to do special things to your environment
    to run it (edit config files etc)
    27

    View Slide

  28. @eldudi #TDDPoznan
    A 100 ms tests is a
    very slow test.
    28

    View Slide

  29. @eldudi #TDDPoznan
    1500 tests each running 100
    ms. That’s 150 seconds. Two
    and a half minutes.
    29

    View Slide

  30. @eldudi #TDDPoznan
    Where does TDD fit in
    all this?
    30

    View Slide

  31. @eldudi #TDDPoznan
    Test Driven
    Development
    31

    View Slide

  32. @eldudi #TDDPoznan
    Test Driven
    Development
    32

    View Slide

  33. @eldudi #TDDPoznan
    In TDD you always
    write test first. Always.
    33

    View Slide

  34. @eldudi #TDDPoznan
    TDD is not “just adding
    tests first”. It’s a complete
    workflow.
    34

    View Slide

  35. @eldudi #TDDPoznan
    TDD is a great way to
    determine how complex your
    code has become.
    You just have to listen.
    35

    View Slide

  36. @eldudi #TDDPoznan
    Have to fake seven
    objects to isolate test?
    36

    View Slide

  37. @eldudi #TDDPoznan
    Have to inject a fake
    into a fake into a fake?
    37

    View Slide

  38. @eldudi #TDDPoznań
    Your test setup
    method has 70 lines?
    38

    View Slide

  39. @eldudi #TDDPoznan
    You need to simulate five
    events to test one
    method?
    39

    View Slide

  40. @eldudi #TDDPoznan
    This always points to an
    overcomplicated design.
    And your tests are here to point
    that out. Very clearly.
    40

    View Slide

  41. @eldudi #TDDPoznan
    By writing the test first,
    you're forced into thinking
    what responsibilities given
    object should have.
    41

    View Slide

  42. @eldudi #TDDPoznan
    By writing test first you’re
    becoming a consumer of
    your upcoming API.
    42

    View Slide

  43. @eldudi #TDDPoznan
    Clarify requirements
    43

    View Slide

  44. @eldudi #TDDPoznan
    All behaviors are testable.
    The only thing that is not
    testable is your code
    44

    View Slide

  45. @eldudi #TDDPoznan
    What unit tests
    can’t do?
    45

    View Slide

  46. @eldudi #TDDPoznan
    Unit tests are never a
    guarantee that you
    won’t ship a bug.
    46

    View Slide

  47. @eldudi #TDDPoznan
    But they’re damn good at
    greatly reducing amount
    of bugs. And time spent
    on QA.
    47

    View Slide

  48. @eldudi #TDDPoznan
    Are unit tests an invaluable tool for
    writing great software? Heck yes.
    Am I going to produce a poor product
    if I can’t unit test? Hell no.
    Jonathan Rasmusson
    48
    http://agilewarrior.wordpress.com/2012/10/06/its-not-about-the-unit-tests/

    View Slide

  49. @eldudi #TDDPoznan
    Quick
    49

    View Slide

  50. @eldudi #TDDWarsaw
    Quick
    BDD Testing Framework
    50

    View Slide

  51. @eldudi #TDDPoznan
    Behavior Driven Development
    Test Driven Development
    51

    View Slide

  52. @eldudi #TDDPoznan
    BDD aims to improve
    certain aspect of TDD
    52

    View Slide

  53. @eldudi #TDDPoznan
    BDD tries to help you
    know what to test
    53

    View Slide

  54. @eldudi #TDDPoznan
    When writing tests
    don’t think ‘tests’
    54

    View Slide

  55. @eldudi #TDDPoznan
    Think about
    ‘behaviors’
    55

    View Slide

  56. @eldudi #TDDPoznan
    Think about examples
    how your object should
    behave
    56

    View Slide

  57. @eldudi #TDDPoznan
    Examples should cover
    only the interface of your
    object
    57

    View Slide

  58. @eldudi #TDDPoznan
    Only the interface
    58

    View Slide

  59. @eldudi #TDDPoznań
    Good habits
    59
    • Work outside-in
    • Use examples to clarify requirements
    • Use ubiquitous language

    View Slide

  60. @eldudi #TDDPoznan
    Technical stuff now
    60

    View Slide

  61. @eldudi #TDDPoznan
    Quick
    61

    View Slide

  62. @eldudi #TDDPoznan
    Based on XCTest
    62

    View Slide

  63. @eldudi #TDDPoznan
    Minimalistic
    implementation
    63

    View Slide

  64. @eldudi #TDDPoznan
    Syntax
    64

    View Slide

  65. @eldudi #TDDPoznan
    Configuring tests
    65

    View Slide

  66. @eldudi #TDDPoznan
    Focusing tests
    66

    View Slide

  67. @eldudi #TDDPoznań
    Focusing tests
    fdescribe("Example specs on NSString") {
    fit("lowercaseString returns a new string with
    everything in lower case") {
    fcontext("init with damping") {
    67

    View Slide

  68. @eldudi #TDDPoznan
    PENDING
    68

    View Slide

  69. @eldudi #TDDPoznań
    PENDING
    pending("lowercaseString returns a new string with
    everything in lower case") {}
    69

    View Slide

  70. @eldudi #TDDPoznan
    x’ing tests
    70

    View Slide

  71. @eldudi #TDDPoznań
    x’ing tests
    xdescribe("Example specs on NSString") {
    xit("lowercaseString returns a new string with
    everything in lower case") {
    xcontext("init with damping") {
    71

    View Slide

  72. @eldudi #TDDPoznan
    Unit tests results
    72

    View Slide

  73. @eldudi #TDDWarsaw
    Unit tests results
    How to understand the output?
    73

    View Slide

  74. @eldudi #TDDWarsaw
    Xcode, AppCode,
    Command Line
    All give the same results. Devil is in the details
    74

    View Slide

  75. @eldudi #TDDPoznań
    (…)
    -[SpecSuiteName passing_spec_name]
    Test Case '-[SpecSuiteName passing_spec_name]' started.
    Test Case '-[SpecSuiteName passing_spec_name]' passed
    (0.271 seconds).
    -[SpecSuiteName failling_spec_name]
    Test Case '-[SpecSuiteName failling_spec_name]' started.
    Test Case '-[SpecSuiteName failling_spec_name]' failed
    (0.002 seconds).
    (…)
    Executed 2 tests, with 1 failure (1 unexpected) in 0.273
    (0.278) seconds
    2 tests; 0 skipped; 1 failure; 1 exception; 0 pending
    75

    View Slide

  76. @eldudi #TDDPoznań
    (…)
    -[SpecSuiteName passing_spec_name]
    Test Case '-[SpecSuiteName passing_spec_name]' started.
    Test Case '-[SpecSuiteName passing_spec_name]' passed
    (0.271 seconds).
    -[SpecSuiteName failling_spec_name]
    Test Case '-[SpecSuiteName failling_spec_name]' started.
    Test Case '-[SpecSuiteName failling_spec_name]' failed
    (0.002 seconds).
    (…)
    Executed 2 tests, with 1 failure (1 unexpected) in 0.273
    (0.278) seconds
    2 tests; 0 skipped; 1 failure; 1 exception; 0 pending
    76

    View Slide

  77. @eldudi #TDDPoznań
    (…)
    -[SpecSuiteName passing_spec_name]
    Test Case '-[SpecSuiteName passing_spec_name]' started.
    Test Case '-[SpecSuiteName passing_spec_name]' passed
    (0.271 seconds).
    -[SpecSuiteName failling_spec_name]
    Test Case '-[SpecSuiteName failling_spec_name]' started.
    Test Case '-[SpecSuiteName failling_spec_name]' failed
    (0.002 seconds).
    (…)
    Executed 2 tests, with 1 failure (1 unexpected) in 0.273
    (0.278) seconds
    2 tests; 0 skipped; 1 failure; 1 exception; 0 pending
    77

    View Slide

  78. @eldudi #TDDPoznań
    (…)
    -[SpecSuiteName passing_spec_name]
    Test Case '-[SpecSuiteName passing_spec_name]' started.
    Test Case '-[SpecSuiteName passing_spec_name]' passed
    (0.271 seconds).
    -[SpecSuiteName failling_spec_name]
    Test Case '-[SpecSuiteName failling_spec_name]' started.
    Test Case '-[SpecSuiteName failling_spec_name]' failed
    (0.002 seconds).
    (…)
    Executed 2 tests, with 1 failure (1 unexpected) in 0.273
    (0.278) seconds
    2 tests; 0 skipped; 1 failure; 1 exception; 0 pending
    78

    View Slide

  79. @eldudi #TDDPoznań
    (…)
    -[SpecSuiteName passing_spec_name]
    Test Case '-[SpecSuiteName passing_spec_name]' started.
    Test Case '-[SpecSuiteName passing_spec_name]' passed
    (0.271 seconds).
    -[SpecSuiteName failling_spec_name]
    Test Case '-[SpecSuiteName failling_spec_name]' started.
    Test Case '-[SpecSuiteName failling_spec_name]' failed
    (0.002 seconds).
    (…)
    Executed 2 tests, with 1 failure (1 unexpected) in 0.273
    (0.278) seconds
    2 tests; 0 skipped; 1 failure; 1 exception; 0 pending
    79

    View Slide

  80. @eldudi #TDDPoznan
    Run your tests from
    command line.
    80

    View Slide

  81. @eldudi #TDDPoznan
    Seriously, do.
    It’s pretty awesome.
    81

    View Slide

  82. @eldudi #TDDPoznan
    “Perfect” setup:
    Have your tests run each
    time you change something
    in a file.
    82

    View Slide

  83. @eldudi #TDDPoznan
    Enhance your tests output.
    83

    View Slide

  84. @eldudi #TDDPoznań
    (…)
    -[SpecSuiteName passing_spec_name]
    Test Case '-[SpecSuiteName passing_spec_name]' started.
    Test Case '-[SpecSuiteName passing_spec_name]' passed
    (0.271 seconds).
    -[SpecSuiteName failling_spec_name]
    Test Case '-[SpecSuiteName failling_spec_name]' started.
    Test Case '-[SpecSuiteName failling_spec_name]' failed
    (0.002 seconds).
    (…)
    Executed 2 tests, with 1 failure (1 unexpected) in 0.273
    (0.278) seconds
    2 tests; 0 skipped; 1 failure; 1 exception; 0 pending
    84

    View Slide

  85. @eldudi #TDDPoznan
    85

    View Slide

  86. @eldudi #TDDWarsaw
    Test Output
    xctool vs xcpretty
    86

    View Slide

  87. @eldudi #TDDPoznań
    Resources & Contact
    @eldudi
    https://github.com/mobile-academy/swift-tdd-workshop-poznan
    [email protected]
    Code Examples
    Contact
    87

    View Slide