Unit Testing in iOS

16bebb36e0e28572a316ba0450e190d1?s=47 Khoa Pham
September 06, 2019

Unit Testing in iOS

I talk about unit testing in iOS and best practices

16bebb36e0e28572a316ba0450e190d1?s=128

Khoa Pham

September 06, 2019
Tweet

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