Passing Arguments and Environment Variables to XCTests
Situations can arise where external information is needed, outside the scope of the XCTest, to configure a test before it’s executed. For example, feature flags or environment variables you would like to pass to your XCTest before running it. In this guide I’ll walkthrough how we can configure our XCTests to accept arguments and environment variables using the Scheme Editor in Xcode.
💡 You can integrate your iOS UI XCTests with Tauk! You can try it for free here: https://www.tauk.com/welcome
Contents of this Guide
- The Scheme Editor in Xcode
- Arguments Passed on Launch
- Recap: Running XCTests from the Command Line
- Environment Variables
The Scheme Editor in Xcode
In Xcode terminology a scheme is a configuration that defines what happens when you “Run”, “Test”, “Build”, or “Profile” your Xcode Project or Workspace. In the case of developing and running XCTests, the “Test” scheme is of primary importance.
From the Xcode, select Product > Scheme > Edit Scheme... from the menu bar.
This will bring up a modal dialog menu. Select the “Test” on the left side and then select “Arguments” from the top section.
From this section we can define what Command Line Arguments or local Environment Variables that can be passed to our XCTests.
Arguments Passed on Launch
In the Arguments Passed on Launch section of the Scheme Editor in Xcode, we can provide an argument values to be passed to our XCTest before the test. If you click on the “+” button you can provide a named argument. For example, let’s say that you want to pass an argument called DEV_CONFIG.
To check for this argument from code, we can use a class called ProcessInfo
. For example:
let devConfigEnabled = ProcessInfo.processInfo.arguments.contains("DEV_CONFIG")
To disable an argument to be passed on launch, you can uncheck the checkbox next to its name from the Scheme Editor in Xcode. This way, you can toggle the presence of the value without having to delete and re-add it.
⚠️ Note: The arguments you pass on launch have to be defined in the Scheme Editor and can’t be dynamically passed in from the Command Line at the time of test invocation. In order to pass Command Line values at launch we can make use of environment variables, which I’ll explain in the subsequent sections.
Recap: Running XCTests from the Command Line
⚠️ Note: I’ve written a previous blog post on Running XCTests from the Command Line if you want to learn more and become familiar with executing tests outside of the Xcode IDE.
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'
Here’s a quick overview of the parameter flags that were passed to the command:
test
: Run the test action for the specified scheme. This is like selectingProduct > Test
in Xcode.project
orworkspace
: 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.
After the parameter flags we can pass our own custom parameters that utilize our own environment variables.
Environment Variables
Environment variables are a collection of key-value pairs, which you can supply to your XCTest as values. Adding an environment variable is similar to adding an argument. In the Environment Variables section of the Scheme Editor, click on the “+” button. This will allow you to supply a name and value. The name you supply will be the key you use to retrieve the value from code. For the value, we can provide an environment variable you want to access.
💡Refresher on Environment Variables
To set environment variables in your command line shell session we can export the variable:
$ export EXAMPLE_VAR="Hello World"
To access the value of the variable, we can prefix the variable with the “$” sign. For example, if we want to print out the value of the variable to our shell.
$ echo $EXAMPLE_VAR
It’s common to store a set of environment variables in a dotfile in your Xcode Project or Workspace folder and source the dotfile before you execute your XCTest. For example, when integrating your XCTests with platforms like Tauk.com, you can store your API TOKEN and PROJECT ID in a dotfile so that it isn’t stored in your code and access the values from within from your XCTest.
$ source .env
For more information on environment variables, I recommend reading this brief overview on Opensource.com.
To retrieve the environment variables from code, we can use the ProcessInfo
class. For example:
ProcessInfo.processInfo.environment["TAUK_API_TOKEN"]
Accessing the environment variable is akin to retrieving a value from a dictionary for a given key.
Member discussion