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

Practical Testing Tips - iOS Con London, May 2016

Practical Testing Tips - iOS Con London, May 2016

The London 2016 Edition of my smorgasboard of unit and UI testing tips. Links to sample code at the end of the presentation.

Ellen Shapiro

May 26, 2016

More Decks by Ellen Shapiro

Other Decks in Technology


  1. PRACTICAL TESTING TIPS by Ellen Shapiro | ios con London

    2016 spothero.com | justhum.com | designatednerd.com | @designatednerd
  2. Why don't developers write tests?

  3. "I Don't have time to Write tests"

  4. Writing Tests lets you refactor faster and with more confidence

  5. Writing tests puts your time costs up front

  6. Writing tests catches your mistakes as you make them

  7. "I Have No idea where to start"

  8. [ Demo: Super-Basic Testing ]

  9. What should you test?

  10. Test The Stuff That Breaks A Lot

  11. "That's called software."

  12. Test The Stuff That is easier for a robot than

    for you to test
  13. Your computer is an awesome robot you can use to

    do your evil bidding.
  14. [ Demo: Time Converter 24 ]

  15. Test The Stuff That is mission-critical

  16. if it breaks, will your users do this?

  17. [ Demo: Core data testing ]

  18. None
  19. Core Data Demo Recap » When you see something that

    can cause a key piece of your app to break, test it. » When testing core data, test the NSInMemoryStoreType so you always have a clean database. » Version your databases!
  20. Test The Stuff That Depends On Someone Else

  21. Is it my code? or Is it their code?

  22. Test it with something that looks like the real thing.

  23. Mock testing

  24. Verifying Did this do what it was supposed to?

  25. Stubbing Fake it 'til you make it

  26. Spying Faking PART of an object

  27. Objective-C Mocking tools OCMock OCMockito

  28. [ Demo: Making a Mockery ]

  29. Objective-C Mock Demo Recap » Make a fake thing »

    Tell it what to do » Pass it to the thing you want to test » Make sure the tested thing reacted properly
  30. Mocking in swift

  31. Swift Inline Class Verification func testThingDoesStuff() { class MockThing :

    Thing { var methodUnderTestWasCalled = false override func methodUnderTest() { //Don't call super! methodUnderTestWasCalled = true } } let testThing = MockThing() testThing.doSomethingThatShouldCallMethodUnderTest() XCTAssertTrue(testThing.methodUnderTestWasCalled) }
  32. Swift Inline Class Stubs/Spies func testThingDoesStuff() { class StubbedThing :

    Thing { override func methodBeingStubbed() -> String { //Don't call super! return "A Known String!" } } let stub = StubbedThing() let tested = ObjectUnderTest() objectUnderTest.thing = stubbed let result = tested.doSomethingThatEventuallyCallsMethodBeingStubbed() XCTAssertTrue(result == "A Known String!") }
  33. Mocking Network Responses

  34. ¡¡ Flagrant plug alert !!

  35. VOKMockUrlProtocol for iOS Mocktrofit for Android open-source projects of Vokal,

    my employers
  36. None
  37. HTTP/1.1 200 OK Server: nginx/1.4.6 (Ubuntu) Date: Wed, 12 Nov

    2014 22:10:40 GMT Content-Type: application/json Transfer-Encoding: chunked Connection: keep-alive Vary: Accept X-Frame-Options: SAMEORIGIN Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS { "default": true, "expiration_month": "10", "expiration_year": "2018", "last_4": "1234", "card_type": "MasterCard", "id": 2 }
  38. { "default": true, "expiration_month": "10", "expiration_year": "2018", "last_4": "1234", "card_type":

    "MasterCard", "id": 2 }
  39. #import "VOKMockURLProtocol.h" @implementation CLTAPIClient (MockData) - (void)setShouldUseMockData:(BOOL)shouldUseMockData { Class mockURLProtocol

    = [VOKMockUrlProtocol class]; NSMutableArray *currentProtocolClasses = [self.sessionConfiguration.protocolClasses mutableCopy]; if (shouldUseMockData) { [currentProtocolClasses insertObject:mockURLProtocol atIndex:0]; } else { [currentProtocolClasses removeObject:mockURLProtocol]; } self.sessionConfiguration.protocolClasses = currentProtocolClasses; } @end
  40. Test your networking logic and your UI against known data

  41. Test networking logic with a live server

  42. Know what you can depend on

  43. Sometimes this can cause a big fight

  44. You are at the mercy of your internet connection

  45. Testing against a live server can change things

  46. Testing against a live server can return different data if

    someone else changed something
  47. Know the limits of what you can test live

  48. Don't lock yourself out

  49. Test that you're getting expected response types, not exact data

  50. Test the things that aren't already covered

  51. Code Coverage tools

  52. Local code coverage

  53. None
  54. None
  55. None
  56. None
  57. Remote code coverage Designed to work with Continuous Integration servers

    » codecov.io » coveralls.io
  58. "I must cover every single line of code"

  59. The most useless test I ever inherited: [Note: class prefixes

    have been changed to protect the guilty]
  60. Don't let the perfect be the enemy of the good

  61. focus on why something needs to be covered rather than

    whether it's covered
  62. How do you write tests?

  63. Test Driven Developlment

  64. You have seen The TDD demo (and it has usually

    taken way too long)
  65. The TL;DR version of the TDD demo

  66. 1. Write a failing test LargerTest.m Larger.m

  67. 1. Write a failing test LargerTest.m Larger.m

  68. 2. Write code to make it pass LargerTest.m Larger.m

  69. 2. Write code to make it pass LargerTest.m Larger.m

  70. 3-∞. Refactor, but now with the guardrails of the test

    LargerTest.m Larger.m
  71. 3-∞. Refactor, but now with the guardrails of the test

    LargerTest.m Larger.m
  72. Repeat for every public method you write.

  73. Behavior Driven Development

  74. Same idea as TDD Different approach

  75. Does it do what it's supposed to for the end

  76. Given / When / Then

  77. You can use libraries to enforce BDD Kiwi Specta Cedar

  78. None
  79. I personally prefer to use XCTest for non-UI tests

  80. [ Demo: BDD in pure XCTest ]

  81. BDD Demo Recap: » Use very descriptive test names. »

    Test the end result, not necessarily how you got there. » Use the XCTest methods you already know. » Use comments if you need the structure of given/ when/then.
  82. UI Testing

  83. A word about XCUI Testing

  84. KIF

  85. Keep It Functional

  86. Kif Pros » Write your UI tests in Objective C!

    » Uses Accessibility, so you make your app accessible in the bargain » Get to the bit you need to test » The most widely used library » Very backwards compatible
  87. Kif Cons » Slow (can be sped up now!) »

    Can be flaky on CI servers » Some folks have had issues with lookup changing the view hierarchy » Very backwards compatible
  88. [ Demo: Kif In Action ]

  89. Testing your UI en muchos idiomas !"#$%&'()

  90. None
  91. !

  92. None
  93. None
  94. UI Testing Recap » If you're swapping out your app

    delegate for tests, make sure you put it back for UI tests » Centralize your localized strings in a convenience class to make strings easier to test » UI and non-UI tests should be separate targets » Add -AppleLanguages "\(en\)" arguments to the test bit of your application's scheme » Duplicate your scheme and update for every language you support
  95. A Final word of warning

  96. Tests do not and cannot catch everything

  97. Tests catch mistakes in the rosy path and known bad

  98. Humans use your application

  99. Humans are weird

  100. Humans multitask

  101. Humans and Robots working together to break your app make

    your app better
  102. Official Summary Slide™ » Testing lets you refactor confidently »

    Testing helps you find out immediately when you broke something so it's easier to fix. » Test as much as you can, however much that is. » Find the testing ideology that works best for you. » UI Testing can give you a great opportunity to see how all the pieces of your app work together. » Have both humans and robots test your app.
  103. Questions?

  104. Things from me or my former employer! #humblebrag » https://github.com/designatednerd/

    TestingPlayground » https://github.com/designatednerd/FlickrSearcher » https://github.com/designatednerd/ DNSiOSLocalizationTestHelpers » https://github.com/vokal/VOKMockUrlProtocol » https://github.com/vokal/Mocktrofit
  105. Mocking tools! » http://ocmock.org/ » https://github.com/jonreid/OCMockito UI Testing Tools! »

    https://github.com/kif-framework/KIF » https://github.com/Raizlabs/FRY
  106. Code Coverage Tools! » https://codecov.io/ » https://coveralls.io » https://github.com/jonreid/XcodeCoverage »

    https://github.com/dropbox/XCoverage » http://www.xcoverageapp.com/
  107. BDD Tools! » https://github.com/specta/specta » https://github.com/kiwi-bdd/Kiwi » https://github.com/pivotal/cedar Other Things

    I Mentioned! » http://ntoll.org/article/tdd-cargo-cult » http://qualitycoding.org/app-delegate-for-tests/
  108. Photo Credits » Angry mob by Robert Course-Baker: https:// www.flickr.com/photos/29233640@N07/3645211083

    » Robot by Logan Ingalls: https://www.flickr.com/ photos/plutor/847695350 » Lock ("Hodgepodged") by David Goehring https:// www.flickr.com/photos/carbonnyc/4740626368/ » All images of Kif from Futurama used without permission. Sorry, Fox.