- Requires Xcode 16
- Builds using Swift 6 without any issues
- Supports all platforms
[.iOS(.v16), .macOS(.v13), .tvOS(.v16), .watchOS(.v9), .visionOS(.v1)]
This framework provides a streamlined solution for unit testing SwiftUI views and dynamic properties, with a focus on hosting views and accessing their state during tests. It offers tools for hosting SwiftUI components and injecting dependencies, enabling developers to verify the correctness and behavior of their user interfaces without modifying production code.
This package consists of a single product:
- ViewHosting: This product is designed for use in your test target only. It provides the tools needed to host views and test dynamic properties like
@State
,@Binding
, and others in a controlled testing environment.
- View Hosting: APIs for hosting views during tests, ensuring controlled testing environments.
- State Access: Easily access and verify view state during tests.
- Dynamic Property Testing: Support for testing views with
@State
,@Binding
, and other property wrappers. - Dependency Injection: Ability to inject dependencies and services during testing.
- Non-Intrusive: No modifications required to production code.
To use this package, add the ViewHosting
product to your test target in your Package.swift
file:
dependencies: [
.package(url: "https://github.com/yourusername/ViewHosting.git", from: "1.0.0"),
],
targets: [
.testTarget(
name: "YourTestTarget",
dependencies: ["ViewHosting"]
),
]
Then, import the framework in your test files:
import ViewHosting
import XCTest
To make your view testable, conform it to the DynamicProperty
protocol in your test file:
extension YourView: DynamicProperty {}
To host and test a view:
func testHostedView() async throws {
let injectedText = UUID().uuidString
let hosted = try TestView().hosted { view in
view.environment(\.loadTextService) {
injectedText
}
}
await hosted.loadText()
XCTAssertEqual(hosted.text, injectedText)
}
You can test dynamic properties independently:
func testHostedState() throws {
let state = try State(initialValue: 0).hosted()
XCTAssertEqual(state.wrappedValue, 0)
state.wrappedValue += 1
XCTAssertEqual(state.wrappedValue, 1)
}
- Dependency Injection: Use the
hosted
method's modification closure to inject dependencies or modify the environment. - Error Handling: The framework includes a custom
HostingError
for handling missing properties. - Performance Testing: Includes performance tests for hosted views and dynamic properties.
We welcome contributions! Please follow these steps:
- Fork the repository and create your branch from
main
. - Ensure your code follows the existing style and architecture.
- Write unit tests for your changes.
- Run all tests to ensure they pass.
- Submit a pull request with a clear description of your changes.
This project is licensed under the MIT License - see the LICENSE file for details.