Running the tests from the command line is a necessary step for Continuous Integration and can come in handy when working solo, too. For example, you might want to run a script to automate publishing a build to TestFlight and run the unit and UI test suites as a pre-check.
Running tests with
When you need to interact with an Xcode project from the terminal,
xcodebuild is the first place to look in.
This command-line tool allows you to perform different actions on an Xcode project or workspace, such as building, archiving, querying information, and of course, testing.
test action is what you use to run tests from a certain scheme in an Xcode project:
xcodebuild \ -project MyAwesomeApp.xcodeproj \ -scheme MyAwesomeApp \ -sdk iphonesimulator \ -destination 'platform=iOS Simulator,name=iPhone 12,OS=14.3' \ test
If your app uses a workspace, perhaps because of CocoaPods, you'll need to pass the
-workspace option instead of
You can run
instruments -s devices to see a list of know devices to use as the
xcodebuild destination cheatsheet for more
-destination tips & tricks.
xcodebuild produces a dense output:
While it's great to have all of the build information at hand, most of it is irrelevant for the tests. And all of that text will make it impossible to scroll back in your terminal window and take up unnecessary space in your CI logs.
Luckily, there are tools to format the raw
xcodebuild input into something concise and informative.
I have two to recommend: the Swift-based
xcbeautify and the Ruby-based
Running tests with
xcbeautify is a little Swift package that makes the
xcodebuild output human-readable.
Once installed, using
xcbeautify is simply a matter of piping the
xcodebuild output through it:
xcodebuild \ -workspace MyAwesomeApp.xcworkspace \ -scheme MyAwesomeApp \ -sdk iphonesimulator \ -destination 'platform=iOS Simulator,name=iPhone 12,OS=14.3' \ test \ | xcbeautify
You can use
xcbeautify the Swift Package Manager and the Bazel build system output, too.
If you are working on a project that doesn't rely on CocoaPods or Fastlane, then
xcbeautify is an excellent and lightweight tool to use.
If, on the other hand, you already have Ruby tooling in your project setup, then it might be simpler to use
Fastlane ships with
xcpretty so you don't have to add an extra step in your CI to install it.
Another scenario in which you might want to use
xcpretty is if you want a different output format as it offers more formatters.
Running tests with
xcpretty, add it to your
Gemfile then run
# Gemfile gem "xcpretty"
You can also install it globally via
gem install xcpretty, but using a
Gemfile to manage your Ruby tools makes it easier for a team and CI to always run on the same versions, avoiding "it works on my machine" issues.
Once you're setup, you can format the
xcodebuild output by piping it through
xcodebuild \ -workspace MyAwesomeApp.xcworkspace \ -scheme MyAwesomeApp \ -sdk iphonesimulator \ -destination 'platform=iOS Simulator,name=iPhone 12,OS=14.3' \ test \ | bundle exec xcpretty
If you set up
gem install, you don't need to call it via
For a more concise output,
xcpretty can use the same formatting style as RSpec, which shows a dot for each test.
Optionally, you can also color the dot green if the test passed or red otherwise.
xcodebuild \ -workspace MyAwesomeApp.xcworkspace \ -scheme MyAwesomeApp \ -sdk iphonesimulator \ -destination 'platform=iOS Simulator,name=iPhone 12,OS=14.3' \ test \ | bundle exec xcpretty --test --color
There are more formatters to choose from and other configuration options you can learn about in the project's
Whether you decide to run your tests with vanilla
xcodebuild or format their output with
xcpretty, I hope you found this tutorial useful.
If you have any questions regarding testing from the command line, leave a comment below or get in touch on Twitter at @mokagio.