Search code examples
xcodetestingcontinuous-integrationxctestxcuitest

Passing environment variables to XCUITest


I run UI tests on CI/CD provider (like CircleCI), I need to read multiple secret environment variables (like testing username and password). I could easily set it but I don't understand how to pass them properly to test cases.

I found 2 ways to do that:

  1. Store it inside shared scheme (in XCode Arguments), it's a bad idea because that secrets shouldn't be stored in git repo.
  2. Injecting variables via text replacement in Swift / Obj-C / xconfig files (like small perl scripts). I don't think that is a good way in 2020.

I use fastlane but haven't found anything about that.

How to do that properly?


Solution

  • Beginning with Xcode 7, environment variables are no longer being passed on to the test binary.

    But, you could pass the environment variable as a build setting and then redefine it as an environment variable for test invocation using the Xcode test scheme configuration.

    For example, assuming you have an environment variable defined called YOUR_SECRET_ENV_VAR, to pass it to Xcode as a build setting from the command line:

    xcrun xcodebuild test
        -workspace your-app.xcworkspace
        -scheme your-app
        -destination 'platform=iOS,name=iPhone'
        YOUR_SECRET_BUILD_VAR=$YOUR_SECRET_ENV_VAR
    

    Then, feed this build setting into your scheme configuration as an environment variable for test invocation. You'll have to uncheck User the Run action's arguments and environment variables.

    configuring environment variables in scheme settings in Xcode UI

    Finally, make use of the environment variable in your test code, using:

    let yourSecret = ProcessInfo.processInfo.environment["YOUR_SECRET_ENV_VAR"]