Unit test your iOS app without Fastlane

Introduction

In this post, I’m going to show you how to run unit tests in your iOS app using the Xcode CLI and Bash. This is a great way to run your tests without having to rely on Fastlane or any other third-party tools. It’s also a good way to get familiar with the Xcode CLI and how it works. You’d want to do this when you have a CI provider that doesn’t have Ruby for some reason, can’t install Fastlane, or just because you want to learn how to do it yourself.

Prerequisites

Setup

You need to know the names of your project and schemes. You can find this out by opening your project in Xcode and looking at the top-left corner of the window. The project name is the name of the file with the .xcodeproj extension, and the scheme is the name of the scheme you want to run tests for. For this example, we’ll use MyApp.xcodeproj and MyAppTests as the scheme name.

#!/bin/bash

set -u  # Only treat unset variables as errors

# Configurable variables
SCHEME="YourSchemeName"
DESTINATION="platform=iOS Simulator,name=iPhone 16 Pro,OS=latest"
PROJECT="YourProject.xcodeproj"

Run tests

We’re going to use xcodebuild to run the tests. This is the command that Xcode uses under the hood to build and run your app. The command looks like this:

#!/bin/bash

set -u  # Only treat unset variables as errors

# Configurable variables
SCHEME="YourSchemeName"
DESTINATION="platform=iOS Simulator,name=iPhone 16 Pro,OS=latest"
PROJECT="YourProject.xcodeproj"

# Run tests and capture exit code
set -o pipefail
xcodebuild test \
-scheme "$SCHEME" \
-project "$PROJECT" \
-destination "$DESTINATION" \
clean test | tee xcodebuild.log | xcpretty

EXIT_CODE=${PIPESTATUS[0]}

if [ "$EXIT_CODE" -ne 0 ]; then
    echo "❌ Unit tests failed!"
    exit "$EXIT_CODE"
else
    echo "✅ All unit tests passed!"
fi

Explanation

Ok, let’s break this down a bit, as it can be quite scary to look at, especially if you’re not used to the command line.

Running the script

To run the script, save it to a file called run_tests.sh and make it executable:

chmod +x run_tests.sh

Then, run the script:

./run_tests.sh

You should see the output of the tests in the console, and if the tests pass, you’ll see a message saying ”✅ All unit tests passed!”. If the tests fail, you’ll see a message saying ”❌ Unit tests failed!” and the script will exit with a non-zero exit code.

Building on top of this

This script is the bare minimum to run unit tests in your iOS app. You can build on top of this by adding more features, such as:

And much more! Bash is incredibly flexible, and xcodebuild is a powerful tool that can do a lot more than just run tests. You can use it to build your app, archive it, export it, and much more. You can find more information about xcodebuild in the Xcode documentation. It’s quite old, but it still has a lot of useful information.

For a list of all the available options for xcodebuild, you can have a look here, and you can always run xcodebuild -help in the terminal to see a list of all the available options.

Conclusion

In this post, we’ve shown you how to run unit tests in your iOS app using the Xcode CLI and Bash. This is a great way to run your tests without having to rely on Fastlane or any other third-party tools. It’s also a good way to get familiar with the Xcode CLI and how it works. Let me know if you have any questions or if you want to see more examples of how to use the Xcode CLI and Bash to run tests in your iOS app. Happy testing!