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

Different flavours of testing in SwiftUI

Different flavours of testing in SwiftUI

A concept of the testing pyramid in practice.

Piotr Torczyński

November 18, 2022
Tweet

Other Decks in Programming

Transcript

  1. About Me • Over 6 years of experience • Currently

    working for Shiftkey • 99% SwiftUI based app • Code coverage ~ 70%
  2. Cuckoo https://github.com/Brightify/Cuckoo • The DSL is very similar to Mockito

    (Android) • Two parts(run time and CuckooGenerator tool) • Supports Inheritance, generics, Objective-C mocks
  3. Resolver https://github.com/hmlongco/Resolver • Supports many injection strategies • Designed for

    performance. It clocks out to be about 800% faster at resolving dependency chains than SwinjectStoryboard.
  4. SwiftUI App Tests • Unit Tests • SwiftUI Views Unit

    Tests • Snapshot Tests • UI Tests
  5. SwiftUI Views Unit Tests View Inspector • Allows for traversing

    a view hierarchy thanks to Swift Re f lection API • Search the view of a speci f ic type or condition • Read the inner state of the standard views • Works with runtime properties (@EnvironmentObject, @State) • Trigger side effects
  6. Snapshot Tests • A software testing method that makes sure

    your UI does not have unexpected changes (i.e. regressions). • We compare the output of a test to a previous test run’s output, called the baseline snapshot. • Are perfect for verifying behavior that changes frequently and is not clearly de f ined (iOS versions changes)
  7. Swifter - Mock Server https://github.com/httpswift/swifter • Tiny HTTP server engine

    written in Swift • Easy to integrate • Can be used to mock network calls for UITests
  8. UI Tests Takes time • XCTestCase.expectation(for:evaluatedWith:handler:) XCTestCase.waitForExpectations(timeout:handler:) with use of

    XCTWaiter let expectation = expectation( for: NSPredicate(format: "exists = = true"), evaluatedWith: app.staticTexts["identif i er"], handler: .none) let result = XCTWaiter.wait(for: [expectation], timeout: 5.0) XCTAssertEqual(result, .completed)
  9. UI Tests Takes time @discardableResult func wait( until expression: @escaping

    (XCUIElement) - > Bool, timeout: UITestTimeout = .standard, message: @autoclosure () - > String = "", f i le: StaticString = #f i le, line: UInt = #line ) - > Self { if expression(self) { return self } let predicate = NSPredicate { _, _ in expression(self) } let expectation = XCTNSPredicateExpectation(predicate: predicate, object: nil) let result = XCTWaiter().wait(for: [expectation], timeout: timeout.rawValue) if result ! = .completed { XCTFail(message().isEmpty ? "expectation not matched after waiting" : message(), f i le: f i le, line: line ) } return self } https://sourcediving.com/clean-waiting-in-xcuitest-43bab495230f
  10. Summary • You can write reliable tests on all levels

    • You can write them fast • Tools can speed up your development