Running XCTests from the Command Line
5 min read

Running XCTests from the Command Line

Running XCTests from the Command Line

Update: I've created a Discord server for discussing all things related to automation testing! Join our community today đź‘‹:

Join the Tauk Discord Server!
Enabling developers to efficiently diagnose, resolve, and optimize their automation tests. | 5 members

Apple’s Xcode IDE provides a comprehensive graphical interface for developing, configuring, and running XCTests. However, in order to tests from a remote server (such as a CI/CD server), you won’t have access to the Xcode IDE and will need to run your tests from the command line. In this guide, we will walkthrough how to use the supplementary xcodebuild command line tool so you can run your automation tests from the terminal with ease.

Contents of this Guide

  • Xcode Command Line Tools
  • Running tests with xcodebuild
  • The Scheme argument
  • The Destination argument
  • iOS Simulator
  • iOS Physical Device
  • Listing Destination options
  • Other xcodebuild arguments
  • Clean Project before running tests
  • Running an individual test

Xcode Command Line Tools

When you’re developing automation tests for a iOS app, Xcode provides a convenient local GUI environment with a plethora of tools. However, this comes at the expense of disk space as it weighs in at ~40 GB. When you want to execute tests from a remote server, you won’t have access to the Xcode GUI and won’t need all of its features.

Apple provides a supplementary Xcode Command Line Tools package that is much more trim, only requires ~3 GB of disk space, and has the essentials to run tests solely from the command line. As a result, you can just install the Xcode Command Line Tools on your remote server and forgo the full Xcode installation.

To install the Xcode Command Line Tools, you can run the following command in your MacOS terminal:

$ xcode-select --install

Note: If you have already installed the Homebrew package manager on your machine, you actually already have the Xcode Command Line Tools. Homebrew relies on it as a dependency, since it needs it to build packages.

To verify that it was installed successfully, you can run the following command in your terminal:

$ xcode-select --print-path

This should return the path where the Xcode Command Line Tools were installed.

Running tests with xcodebuild

xcodebuild is the primary command for both building Xcode projects & running tests and accepts a variety of parameters. The essential xcodebuild command to run a test looks like this:

$ xcodebuild \
 test \
 -project <Your-Project>.xcodeproj \
 -scheme <Your-Scheme> \
 -destination 'platform=iOS Simulator,name=iPhone 13'

I’ll provide a quick overview of the parameters and then go into further detail for each in the upcoming sections.

  • test: Run the test action for the specified scheme. This is like selecting Product > Test in Xcode.
  • -project or -workspace: The path to your Xcode Project (.xcodeproj) or Xcode Workspace file (.xcworkspace).
  • -scheme: A scheme is a specific configuration for your target. It defines what happens when you press “Run”, “Build”, “Test”, etc. in Xcode. Each target has at least one scheme by default and you can customize this in Xcode.
  • -destination: A description of the simulator or physical device you want to run on.

The Scheme Argument

Xcode lets you customize what should happen when you perform an action, such as “Test”, against a target. Using xcodebuild we can list the available schemes for a given Xcode project or workspace target by running the command.

xcodebuild -list -project <Your-Project>.xcodeproj

# OR

xcodebuild -list -workspace <Your-Workspace>.xcworkspace

The available schemes will be listed in the output. For example:

Information about project "NewTaukTestProject":
    Targets:
        NewTaukTestProject
        NewTaukTestProjectTests
        NewTaukTestProjectUITests
    Build Configurations:
        Debug
        Release
    If no build configuration is specified and -scheme is not passed then "Release" is used.
    Schemes:
        NewTaukTestProject

The Destination Argument

The destination argument accepts a key-value pair string. The first key is the platform, which indicates the OS and if your target is a physical device or simulator. The syntax is key=value,key=value,... and note that there is no space separator between commas.

For the platform key, you can specify any of Apple’s supported platforms (macOS, iOS, watchOS, tvOS), but I’ll focus on iOS. For iOS, we can specify if the platform is a local Simulator or a physical device.

iOS Simulator

To target the iOS simulator, we can provide a destination string that at minimum should include a platform key set to iOS Simulator and a name key for the Simulator’s name. For example:

-destination 'platform=iOS Simulator,name=iPhone 13'

You can optionally pass an OS key as well, which is helpful if you have multiple Simulators of the same device type that differ on OS version. For example:

-destination 'platform=iOS Simulator,name=iPhone 13,OS=15.2'

iOS Physical Device

To target a physical iOS device, the platform key will be set to iOS and we can provide either a name key to target the device by its name or id to target it by its UDID. Note: either a name or id must be provided, but not both. If you have multiple devices plugged into your machine, id is convenient to use.

For example:

$ xcodebuild \
 test \
 -project NewTaukTestProject.xcodeproj \
 -scheme NewTaukTestProject \
 -destination 'platform=iOS,name=Nathan's iPhone'

or

$ xcodebuild \
 test \
 -project NewTaukTestProject.xcodeproj \
 -scheme NewTaukTestProject \
 -destination 'platform=iOS,id=00000000-000000000000000'

Listing Destination Options

We can get a listing of all the available device target options by running:

$ xcrun simctl list

xcrun is another companion CLI tool that the Xcode Command Line Tools provide. To get the practical gist on how to use it, please check out this blog post we published.

Other xcodebuild Arguments

Clean Project Before Running Tests

If you want to ensure that the Xcode project or workspace is cleaned before running your tests you add the clean command before test. For example:

$ xcodebuild \
 clean \
 test \
 -project <Your-Project>.xcodeproj \
 -scheme <Your-Scheme> \
 -destination <Your-Destination>

Running an Individual Test

To run an individual test case from your XCTest suite, you can use the -only-testing argument. The format for this argument is slightly different than the others we’ve shown so far and looks like this:

-only-testing:TestBundle/TestSuite/TestCase
  • TestBundle is the group name that holds all your tests. In the Xcode GUI it would be the “folder” name containing your test files in the Project Navigator.
  • TestSuite is the class name of your test.
  • TestCase is the method name of the test within your TestSuite.

For example:

$ xcodebuild \
 test \
 -project NewTaukTestProject.xcodeproj \
 -scheme NewTaukTestProject \
 -destination 'platform=iOS Simulator,name=iPhone 13' \
 -only-testing:NewTaukTestProjectUITests/NewTaukTestProjectUITests/testGetStockPriceForCompany