19

I'd like to pass command line arguments to my iOS tests through the command line (xcodebuild). I'm looking for the equivalent of this setting on XCode:

Arguments

Simply passing the argument to xcodebuild doesn't work, e.g.:

xcodebuild -verbose test -workspace theworkspace.xcworkspace -scheme 'thescheme' -destination 'platform=iOS Simulator,name=iPhone 7' --argument=value

This question is similar to xcodebuild pass arguments to application on iOS but the solution to that question is not satisfactory.

Community
  • 1
  • 1
lzm
  • 827
  • 2
  • 11
  • 25
  • Where you able to figure this out? I am trying to do the same to pass some testing data to my unit tests. – AsH May 31 '17 at 17:17
  • 2
    Possible duplicate of https://stackoverflow.com/questions/23284829/accessing-user-defined-variables-passed-in-from-xcodebuild-command-line – Ivano.Bilenchi Jul 13 '17 at 09:07
  • Did you find a solution for this? It would help us all out if you shared it. – Gabriel Porumb Nov 13 '17 at 14:12
  • This answer works fine (By @Ivano.Bilenchi in above comment). No manual steps needed. https://stackoverflow.com/questions/23284829/accessing-user-defined-variables-passed-in-from-xcodebuild-command-line – Hasaan Ali Aug 29 '18 at 13:30

4 Answers4

9

It's about passing environment variables rather of command line arguments, but it looks like there's a chance it's supported in xcodebuild in Xcode 13. From release notes:

xcodebuild now supports passing certain environment variables to test runner processes. In the environment where xcodebuild is invoked, prefix any variable with TEST_RUNNER_ to pass that variable (with the prefix stripped) to XCTest test runner processes. For example, running env TEST_RUNNER_Foo=Bar xcodebuild test ... causes the environment variable Foo=Bar to be set in the test runner’s environment. (74104870)

Grigory Entin
  • 1,617
  • 18
  • 20
4

You can also try creating a preprocessor macros in the build settings. And then pass a value like this (let's assume it's named DARK_MODE):

xcodebuild -project \
   -scheme  \
   -testPlan  \
   -destination \
   -derivedDataPath \
   DARK_MODE=NO \
   test

And here's how it can be utilized in tests:

override func setUp() {
    super.setUp()
    if ProcessInfo.processInfo.environment["DARK_MODE"] == "YES" {
        SystemSettings.changeUIStyle(to: .dark)
    }
}
ilonska
  • 121
  • 2
2

I didn't manage to find "easy" solution. So instead I split testing in 3 steps:
1. Run xcodebuild build-for-testing. It will generate xctestrun file in derived data, which contains list of launch arguments
2. Add your desire launch arguments here
3. run xcodebuild test-without-building -xctestrun <%path_to_file_here%>

I wrote script for it. It still need some improvements, so in close time I will share its final form.

Edit: Never had time to update script. So here ugly versions, that suit our needs. https://gist.github.com/ManWithBear/57cbabc8dcd0193d156c376d2d23ff02

ManWithBear
  • 2,787
  • 15
  • 27
2

To add to @ManWithBear's answer, I ended up doing this in a script:

#Remove previous command line arguments
/usr/libexec/PlistBuddy -c "Delete DetoxTestRunner:CommandLineArguments" "$TESTRUN" || true
#Add an empty array
/usr/libexec/PlistBuddy -c "Add DetoxTestRunner:CommandLineArguments array" "$TESTRUN"

#Add script arguments as launch arguments of the test runner app
for i in $*; do
  /usr/libexec/PlistBuddy -c "Add DetoxTestRunner:CommandLineArguments: string '$i'" "$TESTRUN"
done

In the code above, I add all arguments passed to a script as launch argument to the tester app. DetoxTestRunner is the name if the test scheme/target.

Léo Natan
  • 56,823
  • 9
  • 150
  • 195