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

Unit Testing in iOS

Khoa Pham
September 06, 2019

Unit Testing in iOS

I talk about unit testing in iOS and best practices

Khoa Pham

September 06, 2019
Tweet

More Decks by Khoa Pham

Other Decks in Programming

Transcript

  1. Unit Testing in iOS

  2. About → Khoa Pham → onmyway133.github.io

  3. None
  4. Unit Test → What → Why → How → Good

    Pratices
  5. F.I.R.S.T. → Fast → Independent → Repeatable → Self validating

    → Timely
  6. What Unit test is code that tests a unit of

    code. → Automate → Trustworthy → Examine all possible cases
  7. Why → Verify → Act as documentation → Decouple components

    → Avoid regression bugs → Refactoring
  8. Code from others

  9. Complex operation

  10. Complex control flow

  11. Assumption

  12. Edge cases

  13. XCTest → Unit tests → Performance tests → UI tests

  14. Property testing property("The reverse of the reverse of an array

    is that array") <- forAll { (xs : [Int]) in return (xs.reverse().reverse() == xs) <?> "Left identity" ^&&^ (xs == xs.reverse().reverse()) <?> "Right identity" }
  15. Snapshot testing class MyViewControllerTests: XCTestCase { func testMyViewController() { let

    vc = MyViewController() assertSnapshot(matching: vc, as: .image) } }
  16. BDD style → Behavior driven developmennt → RSpec describe HelloWorld

    do context “When testing the HelloWorld class” do it "should say 'Hello World' when we call the say_hello method" do hw = HelloWorld.new message = hw.say_hello expect(message).to eq "Hello World!" end end end
  17. BDD in Swift context("a move that was already played") {

    it("should throw an error") { try! board.play(at: 0) // 1 // 2 expect { try board.play(at: 0) } .to(throwError(Board.PlayError.alreadyPlayed)) } }
  18. XCTest class HourFormatterTests: XCTestCase { func testFormat() { let formatter

    = HourFormatter() XCTAssertEqual(formatter.format(minute: 90 ), "01:30") XCTAssertEqual(formatter.format(minute: 120), "02:00") XCTAssertEqual(formatter.format(minute: 660 ), "11:00") } }
  19. TDD → Test driven development → TDD is dead. Long

    live testing https://dhh.dk/ 2014/tdd-is-dead-long-live-testing.html Less emphasis on unit tests, because we're no longer doing test-first as a design practice, and more emphasis on, yes, slow, system tests.
  20. Cons of unit test → Take time → Code change

    → Take time → Compromised test → Take time
  21. Still → It's good to have unit test → Does

    not matter if TDD or not. As long as we have tests → Validate quickly and reliably → Help your future self or other maintainers
  22. Good practices

  23. 1. Test alongside code → Jest https://jestjs.io/

  24. None
  25. 2. Test what you feel need import XCTest @testable import

    Cutters_Staging class LauncScreenTests: XCTestCase { func testLaunchScreen() { let launchScreen = UIStoryboard(name: "LaunchScreen", bundle: nil) let viewController = launchScreen.instantiateInitialViewController()! let label = viewController.view.subviews.compactMap({ $0 as? UILabel }).first! XCTAssertEqual(label.text, "Cut time. Cut hair. Cut cost.") let imageView = viewController.view.subviews.compactMap({ $0 as? UIImageView }).first! XCTAssertNotNil(imageView.image) } }
  26. 3. View be dumb → Decouple representation (view) from computation

    (logic) → Model - View - Controller → Test logic → And can also test UI
  27. None
  28. 4. Mock → Mock during development → Mock during testing

    final class Deps { static let salonRepo: SalonRepoAware = SalonRepo() static let userRepo: UserRepoAware = UserRepo() static let cardRepo: CardRepoAware = CardRepo() }
  29. None
  30. 5. Commit hook → pre-commit marker="<TEST>" test $(git diff --cached

    -z $against | grep $marker | wc -c) != 0
  31. 6. Coverage → Code coverage != Test coverage → 100%

    code coverage
  32. None
  33. 7. Continuous integration → Jenkins → Bitrise → Circle →

    Xcode Server
  34. None
  35. 8. Xcode → XCTWaiter Xcode 8.3 → XCUISiriService in Xcode

    9 → Parallel testing Xcode 10 → XCTestPlan Xcode 11 → Simulation, random order, attachment, activity, ...
  36. None
  37. $ xcodebuild test -scheme MyApp \ -destination "plaform=iOS,name=iPhone 8" \

    -destination "platform=iOS,name=iPhone 8 Plus"
  38. One more thing https://www.youtube.com/watch?v=D-dj_cwdVYg

  39. Thank you M̶a̶y̶ ̶t̶h̶e̶ ̶f ̶o̶r̶c̶e̶ ̶b̶e̶ ̶w̶ i ̶

    t̶h̶ ̶y̶o̶u̶ May your code continue to compile