ios testing expert

Comprehensive testing patterns for iOS apps.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "ios testing expert" with this command: npx skills add willsigmon/sigstack/willsigmon-sigstack-ios-testing-expert

iOS Testing Expert

Comprehensive testing patterns for iOS apps.

Testing Pyramid for iOS

 /\        E2E (XCUITest) - 10%
/  \       UI Tests, full flows

/----
/ \ Integration - 20% / \ ViewModels + Services /----------
/ \ Unit - 70% \ Models, Utils, Pure Logic

XCTest Basics

Unit Test

import XCTest @testable import App

final class UserTests: XCTestCase {

func testUserFullName() {
    let user = User(firstName: "John", lastName: "Doe")
    XCTAssertEqual(user.fullName, "John Doe")
}

func testUserValidation() throws {
    let user = User(email: "invalid")
    XCTAssertThrowsError(try user.validate())
}

}

Async Testing

func testAsyncFetch() async throws { let service = UserService() let user = try await service.fetch(id: "123") XCTAssertEqual(user.id, "123") }

// Or with expectations func testAsyncWithExpectation() { let expectation = expectation(description: "fetch")

service.fetch(id: "123") { result in
    XCTAssertNotNil(result)
    expectation.fulfill()
}

wait(for: [expectation], timeout: 5)

}

XCUITest (UI Tests)

Basic UI Test

import XCUITest

final class LoginUITests: XCTestCase { let app = XCUIApplication()

override func setUpWithError() throws {
    continueAfterFailure = false
    app.launch()
}

func testLogin() throws {
    app.textFields["email"].tap()
    app.textFields["email"].typeText("test@example.com")

    app.secureTextFields["password"].tap()
    app.secureTextFields["password"].typeText("password123")

    app.buttons["Login"].tap()

    XCTAssertTrue(app.staticTexts["Welcome"].waitForExistence(timeout: 5))
}

}

Accessibility Identifiers

// In your SwiftUI View TextField("Email", text: $email) .accessibilityIdentifier("email")

// In UI Test app.textFields["email"].tap()

Quick/Nimble (BDD Style)

Setup

// Package.swift .package(url: "https://github.com/Quick/Quick.git", from: "7.0.0"), .package(url: "https://github.com/Quick/Nimble.git", from: "13.0.0"),

BDD Test

import Quick import Nimble @testable import App

final class UserSpec: QuickSpec { override class func spec() { describe("User") { var user: User!

        beforeEach {
            user = User(firstName: "John", lastName: "Doe")
        }

        context("when valid") {
            it("has a full name") {
                expect(user.fullName).to(equal("John Doe"))
            }

            it("can be validated") {
                expect { try user.validate() }.toNot(throwError())
            }
        }

        context("when email is invalid") {
            beforeEach {
                user.email = "invalid"
            }

            it("throws validation error") {
                expect { try user.validate() }.to(throwError())
            }
        }
    }
}

}

Mocking with Protocols

Protocol-Based DI

protocol UserServiceProtocol { func fetch(id: String) async throws -> User }

// Real implementation class UserService: UserServiceProtocol { func fetch(id: String) async throws -> User { // Network call } }

// Mock for testing class MockUserService: UserServiceProtocol { var mockUser: User? var shouldFail = false

func fetch(id: String) async throws -> User {
    if shouldFail { throw APIError.failed }
    return mockUser ?? User(id: id)
}

}

Testing with Mock

func testViewModelLoadsUser() async { let mockService = MockUserService() mockService.mockUser = User(id: "1", name: "Test")

let viewModel = UserViewModel(service: mockService)
await viewModel.load()

XCTAssertEqual(viewModel.user?.name, "Test")

}

Snapshot Testing

swift-snapshot-testing

import SnapshotTesting import SwiftUI

func testUserProfileView() { let view = UserProfileView(user: .mock)

assertSnapshot(
    of: view,
    as: .image(layout: .device(config: .iPhone13))
)

}

Test Coverage

Enable Coverage

xcodebuild test
-scheme App
-enableCodeCoverage YES
-resultBundlePath TestResults.xcresult

View Report

xcrun xccov view --report TestResults.xcresult

Use when: Writing iOS tests, setting up testing infrastructure, mocking

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

swiftlint-autofix

No summary provided by upstream source.

Repository SourceNeeds Review
General

bitrise expert

No summary provided by upstream source.

Repository SourceNeeds Review
General

fastlane expert

No summary provided by upstream source.

Repository SourceNeeds Review