Back to Skills

swiftui-testing

verified

Test SwiftUI apps with XCTest, UI tests, snapshot testing, and async testing. Use when writing unit tests for ViewModels, creating UI automation tests, implementing snapshot tests, or testing async code.

View on GitHub

Marketplace

fusengine-plugins

fusengine/agents

Plugin

fuse-swift-apple-expert

development

Repository

fusengine/agents

plugins/swift-apple-expert/skills/swiftui-testing/SKILL.md

Last Verified

January 22, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/fusengine/agents/blob/main/plugins/swift-apple-expert/skills/swiftui-testing/SKILL.md -a claude-code --skill swiftui-testing

Installation paths:

Claude
.claude/skills/swiftui-testing/
Powered by add-skill CLI

Instructions

# SwiftUI Testing

## Unit Testing ViewModels

```swift
@MainActor
final class ProfileViewModelTests: XCTestCase {
    var sut: ProfileViewModel!
    var mockRepository: MockUserRepository!

    override func setUp() {
        super.setUp()
        mockRepository = MockUserRepository()
        sut = ProfileViewModel(repository: mockRepository)
    }

    override func tearDown() {
        sut = nil
        mockRepository = nil
        super.tearDown()
    }

    func testLoadUser_Success() async {
        // Given
        let expectedUser = User(id: "1", name: "John")
        mockRepository.stubbedUser = expectedUser

        // When
        await sut.loadUser(id: "1")

        // Then
        XCTAssertEqual(sut.user, expectedUser)
        XCTAssertFalse(sut.isLoading)
        XCTAssertNil(sut.error)
    }

    func testLoadUser_Failure() async {
        // Given
        mockRepository.shouldFail = true

        // When
        await sut.loadUser(id: "1")

        // Then
        XCTAssertNil(sut.user)
        XCTAssertNotNil(sut.error)
    }
}
```

## Mock Repository Pattern

```swift
final class MockUserRepository: UserRepositoryProtocol, @unchecked Sendable {
    var stubbedUser: User?
    var shouldFail = false
    var fetchCallCount = 0

    func fetch(id: String) async throws -> User {
        fetchCallCount += 1
        if shouldFail {
            throw NSError(domain: "Test", code: -1)
        }
        return stubbedUser ?? User(id: id, name: "Test")
    }
}
```

## UI Testing with Accessibility

```swift
final class ProfileUITests: XCTestCase {
    var app: XCUIApplication!

    override func setUp() {
        continueAfterFailure = false
        app = XCUIApplication()
        app.launchArguments = ["UI_TESTING"]
        app.launch()
    }

    func testProfileFlow() {
        // Navigate to profile
        let profileTab = app.tabBars.buttons["Profile"]
        XCTAssertTrue(profileTab.waitForExistence(timeout: 5))
        profileTab.tap()

        // Ve

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
3255 chars