Fleet is a UIKit-focused testing framework intended for use on iOS and tvOS projects written in Swift.
The next major release supports iOS 15 and tvOS 15 through Swift Package Manager. This checkout contains the package and hosted consumer checks; no new major version is published yet. See SwiftPM installation and compatibility and distribution for setup and the migration policy. Fleet uses Swift 6 language mode; UIKit tests call its helpers on @MainActor and run serially.
For existing Fleet 4.x releases, consult the historical iOS or tvOS installation guidance.
Fleet allows test code to inject into and pull mocks from storyboards. This gives you the best of both worlds -- ability to test your view controllers and their interactions with each other exactly as they are in production code without compromising the ability to isolate any particular view controller for unit testing purposes.
Read more about using Fleet's storyboard features in the Documentation section.
Fleet extends UIKit classes in order to make it easier to test your code's interactions with UIKit. Following are summaries of the major features for each extended class. The Documentation folder contains more information about these features, as well as sample code showing you how they are intended to be used.
- UIViewController - Makes the UI run-loop behave more consistently to allow specs to test view controller presentation and dismissal with less effort.
- UITableView - Provides methods mimicking user actions on table views, ensuring all appropriate delegate and data source callbacks are run.
- UINavigationController - Allows specs to test pushing and popping on the navigation stack without waiting for the UI run-loop.
- UIButton - Provides convenience methods for interacting with buttons in test.
- UIBarButtonItem - Provides convenience methods similar to those provided for UIButton.
- UIAlertController - Allows specs to simply tap on alert actions in order to test their behavior.
- UITabBarController - Provides convenience methods for selecting tabs.
- UINavigationBar - Tap on items in a navigation bar.
- UITextField - Provides convenience methods for entering text. (iOS-only)
- UISwitch - Provides convenience methods for interacting with switches in test. (iOS-only)
- UITextView - Provides convenience methods for entering text into a text view. (iOS-only)
- UIToolbar - Tap on items in a toolbar. (iOS-only)
Fleet provides another method of help in setting up view controller alongside storyboard injection and mocking. It makes it easy to set your view controllers up in a proper key application window by providing the following methods:
// Takes a `UIViewController`, makes it the test app key window's root, and kicks off its lifecycle.
Fleet.setAsAppWindowRoot(_:)
// Takes a `UIViewController`, makes it the root of a navigation stack, kicks off the lifecycle, and
// returns the navigation controller that hosts that view controller.
Fleet.setInAppWindowRootNavigation(_:)Fleet highly recommends that all view controller tests run inside the test host's key window using one of the above methods. For more discussion on why, go to the relevant section in the FAQ.
- Does Fleet do lots of swizzling to provide its features?
- I could accomplish the same thing by calling all the delegate methods and events myself, right?
- Why does Fleet raise exceptions and how should I handle them?
- Why should I make sure all UIViewController unit tests happen in a UIWindow?
To get you started with Fleet, we've created a real, working project that is fully test-driven with the help of Fleet, and which contains many examples of basic tests that you'll likely write in any Swift iOS application.
For more complicated, larger-scale projects that use Fleet, check out the following projects:
The modernization checklist tracks the work needed to restore a maintained build, verify current UIKit behavior, and resume regular feature development.
For development, run script/test for iOS or script/test all for iOS and tvOS. See CONTRIBUTING.md for setup and AGENTS.md for repository guidance.
Release preparation, validation, and publication use separate commands documented in Releasing Fleet. Publication requires validated packaging and external consumer tests.