Successfully reported this slideshow.

Swift testing ftw

1

Share

1 of 35
1 of 35

Swift testing ftw

1

Share

Download to read offline

Talk for the Appsterdam community 20150520:
Brief introduction to unit testing and some of the most relevant aspect of writing unit tests in Swift.

Talk for the Appsterdam community 20150520:
Brief introduction to unit testing and some of the most relevant aspect of writing unit tests in Swift.

More Related Content

Related Books

Free with a 14 day trial from Scribd

See all

Related Audiobooks

Free with a 14 day trial from Scribd

See all

Swift testing ftw

  1. 1. Swift Testing FTW! Jorge D. Ortiz-Fuentes @jdortiz #SwiftTesting
  2. 2. A Canonical Examples production #SwiftTesting
  3. 3. #SwiftTesting Agenda ★ Basics about unit testing ★ 4 challenges of Swift Testing ★ Proposed enhancements
  4. 4. Basics about Unit Testing
  5. 5. But my code is always awesome!
  6. 6. #SwiftTesting Unit Tests ★ Prove correctness of different aspects of the public interface. • Prove instead of intuition • Define contract and assumptions • Document the code • Easier refactoring or change ★ Reusable code = code + tests
  7. 7. #SwiftTesting Use Unit Testing Incrementally ★ You don’t have to write every unit test ★ Start with the classes that take care of the logic • If mixed apply SOLID ★ The easier entry point is fixing bugs
  8. 8. Time writing tests < Time debugging
  9. 9. Ask for your wishes
  10. 10. #SwiftTesting Types of Unit Tests ★ Test return value ★ Test state ★ Test behavior
  11. 11. #SwiftTesting The Rules of Testing ★ We only test our code ★ Only a level of abstraction ★ Only public methods ★ Only one assertion per test ★ Tests are independent of sequence or state
  12. 12. 4 Challenges of Swift Testing
  13. 13. Lost
  14. 14. #SwiftTesting New to Swift ★ Still learning the language ★ Functional Paradigm ★ Swift has bugs
  15. 15. #SwiftTesting Implicitly unwrapped SUT ★ SUT cannot be created in init ★ Thus, it needs to be optional ★ But once set in setUp, it never becomes nil ★ Syntax is clearer with an implicitly unwrapped optional.
  16. 16. #SwiftTesting XCTAssertEquals ★ Works with non custom objects ★ But requires objects to be equatable ★ Use reference comparison instead
  17. 17. #SwiftTesting func createSut() { interactor = ShowAllSpeakersInteractorMock() sut = SpeakerListPresenter(interactor: interactor) view = SpeakersListViewMock() sut.view = view } func testViewIsPersisted() { if let persitedView = shut.view as? SpeakersListViewMock { XCTAssertTrue(persistedView === view, “Wrong view persisted”) } else { XCTFail(“View must be persisted”) } } Example: Test persistence public class SpeakersListPresenter { let interactor: ShowAllSpeakersInteractorPro tocol public weak var view SpeakersListViewProtocol? public init(interactor: ShowAllSpeakersInteractorPro tocol) { self.interactor = interaction } }
  18. 18. No Courage
  19. 19. #SwiftTesting Room for improvement ★ Brian Gesiak: XCTest: The Good Parts: • Replace/customize Testing frameworks • XCTAssertThrows • assert/precondition • 1,000+ tests ★ I add: • Run tests without the simulator • Jon Reid provides a method to speed up AppDelegate launch, but not for Swift
  20. 20. No Brains
  21. 21. #SwiftTesting Access control NTFTC ★ It would be nice to have access to internal properties, but you should only test the public interface ★ Implicit constructors for structs are internal ★ However, mocks defined in the same test case can be accessed (internal) ★ If not tested, view controllers may not be public. But it makes things more complicated. More on that later.
  22. 22. #SwiftTesting Create your own templates import XCTest import ___PACKAGENAMEASIDENTIFIER___ class ___FILEBASENAMEASIDENTIFIER___: ___VARIABLE_testSubclass___ { // MARK: - Parameters & Constants // MARK: - Test vatiables. var sut: ___VARIABLE_classUnderTest___! // MARK: - Set up and tear down override func setUp() { super.setUp() createSut() } func createSut() { sut = ___VARIABLE_classUnderTest___() } override func tearDown() { releaseSut() super.tearDown() } func releaseSut() { sut = nil }
  23. 23. No Heart
  24. 24. #SwiftTesting Dependency Injection ★ Code of an object depends on other objects. ★ Those are considered dependencies. ★ Dependencies must be controlled in order to reproduce behavior properly.
  25. 25. #SwiftTesting Dependency Injection ★ Extract and override: move to a method and override in testing class (more fragile) ★ Method injection: change the signature of the method to provide the dependency ★ Property injection: lazy instantiation ★ Constructor injection: not always possible
  26. 26. #SwiftTesting Stubs & Mocks ★ Both are fake objects ★ Stubs provide desired responses to the SUT ★ Mocks also expect certain behaviors
  27. 27. OCMock / OCMockito Not Available!
  28. 28. #SwiftTesting Testing with dependency class ViewController: UIViewController { @IBOutlet weak var messageLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() let userDefaults = NSUserDefaults.standardUserDefaults() let score = userDefaults.integerForKey("PreservedScore") messageLabel.text = String(score) } }
  29. 29. #SwiftTesting func testMessageLabelDisplaysStoredScore() { var labelMock = LabelMock() sut.messageLabel = labelMock sut.userDefaults = UserDefaultsMock() var view = sut.view if let text = sut.messageLabel.text { XCTAssertEqual(text, "1337", "Label must display the preserved score.") } else { XCTFail("Label text must not be nil.") } } class UserDefaultsMock: NSUserDefaults { override func integerForKey(defaultName: String) -> Int { return 1337 } } class LabelMock: UILabel { var presentedText: String? override internal var text: String? { get { return presentedText } set { presentedText = newValue } } } } Dependency injection import UIKit public class ViewController: UIViewController { @IBOutlet public weak var messageLabel: UILabel! lazy public var userDefaults = NSUserDefaults.standardUserDefaults() override public func viewDidLoad() { super.viewDidLoad() let score = userDefaults.integerForKey("Score") messageLabel.text = String(score) } }
  30. 30. Let the Architecture Help You
  31. 31. #SwiftTesting Clean Architecture View (VC) Presenter Wireframe Interactor Repository Persistence WSC
  32. 32. Follow the Clean Brick Road
  33. 33. canonicalexamples.com coupon: APPSTERDAMERS
  34. 34. Thank you!
  35. 35. @jdortiz #SwiftTesting

×