Poznan TDD Workshop Part 1

Poznan TDD Workshop Part 1

15633e65c96546d830fb84ee7fe5db9c?s=128

Pawel Dudek

June 18, 2016
Tweet

Transcript

  1. Mobile Academy

  2. Mobile Academy @eldudi #TDDPoznan

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

  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.
  5. @eldudi #TDDPoznan Um… what? 5

  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.
  7. @eldudi #TDDPoznan What is an app? 7

  8. @eldudi #TDDPoznan An app is a set of behaviours created

    by programmer and expected by user. 8
  9. @eldudi #TDDPoznan We, programmers, have a limited cognition. As all

    humans do. 9
  10. @eldudi #TDDPoznan We can’t always ‘load’ all of the code

    of our app into our memory. 10
  11. @eldudi #TDDPoznan This means that we can, by accident, change

    the behaviour of the app. 11
  12. @eldudi #TDDPoznan Preserving behaviour of complex systems is hard. In

    fact, of any system at all. 12
  13. @eldudi #TDDPoznan Enter unit tests. 13

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

    app behaviour is preserved. 14
  15. @eldudi #TDDPoznan What is a unit test? 15

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

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

    in isolation with test code 17
  18. @eldudi #TDDPoznan Test isolation 18

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

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

    Fake cook 20
  21. @eldudi #TDDPoznan Why isolate? 21

  22. @eldudi #TDDPoznan Unit test lifecycle 22

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

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

    test? 24
  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
  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
  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
  28. @eldudi #TDDPoznan A 100 ms tests is a very slow

    test. 28
  29. @eldudi #TDDPoznan 1500 tests each running 100 ms. That’s 150

    seconds. Two and a half minutes. 29
  30. @eldudi #TDDPoznan Where does TDD fit in all this? 30

  31. @eldudi #TDDPoznan Test Driven Development 31

  32. @eldudi #TDDPoznan Test Driven Development 32

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

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

    a complete workflow. 34
  35. @eldudi #TDDPoznan TDD is a great way to determine how

    complex your code has become. You just have to listen. 35
  36. @eldudi #TDDPoznan Have to fake seven objects to isolate test?

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

    into a fake? 37
  38. @eldudi #TDDPoznań Your test setup method has 70 lines? 38

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

    one method? 39
  40. @eldudi #TDDPoznan This always points to an overcomplicated design. And

    your tests are here to point that out. Very clearly. 40
  41. @eldudi #TDDPoznan By writing the test first, you're forced into

    thinking what responsibilities given object should have. 41
  42. @eldudi #TDDPoznan By writing test first you’re becoming a consumer

    of your upcoming API. 42
  43. @eldudi #TDDPoznan Clarify requirements 43

  44. @eldudi #TDDPoznan All behaviors are testable. The only thing that

    is not testable is your code 44
  45. @eldudi #TDDPoznan What unit tests can’t do? 45

  46. @eldudi #TDDPoznan Unit tests are never a guarantee that you

    won’t ship a bug. 46
  47. @eldudi #TDDPoznan But they’re damn good at greatly reducing amount

    of bugs. And time spent on QA. 47
  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/
  49. @eldudi #TDDPoznan Quick 49

  50. @eldudi #TDDWarsaw Quick BDD Testing Framework 50

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

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

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

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

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

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

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

    object 57
  58. @eldudi #TDDPoznan Only the interface 58

  59. @eldudi #TDDPoznań Good habits 59 • Work outside-in • Use

    examples to clarify requirements • Use ubiquitous language
  60. @eldudi #TDDPoznan Technical stuff now 60

  61. @eldudi #TDDPoznan Quick 61

  62. @eldudi #TDDPoznan Based on XCTest 62

  63. @eldudi #TDDPoznan Minimalistic implementation 63

  64. @eldudi #TDDPoznan Syntax 64

  65. @eldudi #TDDPoznan Configuring tests 65

  66. @eldudi #TDDPoznan Focusing tests 66

  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
  68. @eldudi #TDDPoznan PENDING 68

  69. @eldudi #TDDPoznań PENDING pending("lowercaseString returns a new string with everything

    in lower case") {} 69
  70. @eldudi #TDDPoznan x’ing tests 70

  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
  72. @eldudi #TDDPoznan Unit tests results 72

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

    73
  74. @eldudi #TDDWarsaw Xcode, AppCode, Command Line All give the same

    results. Devil is in the details 74
  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
  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
  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
  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
  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
  80. @eldudi #TDDPoznan Run your tests from command line. 80

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

  82. @eldudi #TDDPoznan “Perfect” setup: Have your tests run each time

    you change something in a file. 82
  83. @eldudi #TDDPoznan Enhance your tests output. 83

  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
  85. @eldudi #TDDPoznan 85

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

  87. @eldudi #TDDPoznań Resources & Contact @eldudi https://github.com/mobile-academy/swift-tdd-workshop-poznan pawel@dudek.mobi Code Examples

    Contact 87