Slide 1

Slide 1 text

Mobile Academy

Slide 2

Slide 2 text

Mobile Academy @eldudi #TDDPoznan

Slide 3

Slide 3 text

What is a unit test? @eldudi #TDDWarsaw

Slide 4

Slide 4 text

@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.

Slide 5

Slide 5 text

@eldudi #TDDPoznan Um… what? 5

Slide 6

Slide 6 text

@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.

Slide 7

Slide 7 text

@eldudi #TDDPoznan What is an app? 7

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

@eldudi #TDDPoznan Enter unit tests. 13

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

@eldudi #TDDPoznan What is a unit test? 15

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

@eldudi #TDDPoznan Test isolation 18

Slide 19

Slide 19 text

@eldudi #TDDPoznań processOrder getDishes 19 Table Waiter Cook

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

@eldudi #TDDPoznan Why isolate? 21

Slide 22

Slide 22 text

@eldudi #TDDPoznan Unit test lifecycle 22

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

@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

Slide 26

Slide 26 text

@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

Slide 27

Slide 27 text

@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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

@eldudi #TDDPoznan Test Driven Development 31

Slide 32

Slide 32 text

@eldudi #TDDPoznan Test Driven Development 32

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

@eldudi #TDDPoznan Clarify requirements 43

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

@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/

Slide 49

Slide 49 text

@eldudi #TDDPoznan Quick 49

Slide 50

Slide 50 text

@eldudi #TDDWarsaw Quick BDD Testing Framework 50

Slide 51

Slide 51 text

@eldudi #TDDPoznan Behavior Driven Development Test Driven Development 51

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

@eldudi #TDDPoznan Think about ‘behaviors’ 55

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

@eldudi #TDDPoznan Only the interface 58

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

@eldudi #TDDPoznan Technical stuff now 60

Slide 61

Slide 61 text

@eldudi #TDDPoznan Quick 61

Slide 62

Slide 62 text

@eldudi #TDDPoznan Based on XCTest 62

Slide 63

Slide 63 text

@eldudi #TDDPoznan Minimalistic implementation 63

Slide 64

Slide 64 text

@eldudi #TDDPoznan Syntax 64

Slide 65

Slide 65 text

@eldudi #TDDPoznan Configuring tests 65

Slide 66

Slide 66 text

@eldudi #TDDPoznan Focusing tests 66

Slide 67

Slide 67 text

@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

Slide 68

Slide 68 text

@eldudi #TDDPoznan PENDING 68

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

@eldudi #TDDPoznan x’ing tests 70

Slide 71

Slide 71 text

@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

Slide 72

Slide 72 text

@eldudi #TDDPoznan Unit tests results 72

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

@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

Slide 76

Slide 76 text

@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

Slide 77

Slide 77 text

@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

Slide 78

Slide 78 text

@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

Slide 79

Slide 79 text

@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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

@eldudi #TDDPoznan Enhance your tests output. 83

Slide 84

Slide 84 text

@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

Slide 85

Slide 85 text

@eldudi #TDDPoznan 85

Slide 86

Slide 86 text

@eldudi #TDDWarsaw Test Output xctool vs xcpretty 86

Slide 87

Slide 87 text

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