drekka drekka - 4 months ago 15
iOS Question

launchArguments in UITesting in Xcode 7.3 not working

I've been writing UI tests in Xcode 7.3 and recently wanted to add a launch argument to enable some test code inside the app. I initially tried setting

XCUIApplication().launchArguments
as several people have done in various posts, but they would not work.

Digging around it appears that both
launchArguments
and
launchEnvironment
cannot be setup within a UI test, even though the API documentation says they can.

Further when I attempted to set launch arguments and environment variables in the UI Testing scheme, they also where not passed through to the app, where as when unit testing or running the app, they are.

Here's a copy of a quick tests I did to prove this, all these tests fail.

import XCTest

class LaunchDebugUITests: XCTestCase {

func testLaunchArgumentsSetting() {
XCUIApplication().launchArguments = ["abc"]
print("Arguments \(XCUIApplication().launchArguments)")
XCTAssertTrue(XCUIApplication().launchArguments.contains("abc"))
}

func testLaunchArgumentsAppending() {
XCUIApplication().launchArguments.append("abc")
print("Arguments \(XCUIApplication().launchArguments)")
XCTAssertTrue(XCUIApplication().launchArguments.contains("abc"))
}

func testLaunchEnvironmentSetting() {
XCUIApplication().launchEnvironment = ["abc":"def"]
print("Environment \(XCUIApplication().launchEnvironment)")
XCTAssertEqual("def", XCUIApplication().launchEnvironment["abc"])
}

func testLaunchEnvironmentAppending() {
XCUIApplication().launchEnvironment["abc"] = "def"
print("Environment \(XCUIApplication().launchEnvironment)")
XCTAssertEqual("def", XCUIApplication().launchEnvironment["abc"])
}

}


Has anyone else encountered this? Do you have a work around?

Answer

You need to also, then, launch you app and check in the app for the argument. Here's how I do it...

func testFooBar() {
    // given
    app.launchArguments = ["shouldDoBar", "shouldDoFoo"]

    // when
    app.launch()

    // then
}   

Then in your app

int main(int argc, char *argv[]) {
    NSArray *arguments = [[NSProcessInfo processInfo] arguments];

    if ([arguments containsObject:@"shouldDoBar"]) {
       doBar();
    }

    if ([arguments containsObject:@"shouldDoFoo"]) {
       doFoo();
    }
    ...
}

You might want the arguments checks somewhere more appropriate to your use (and perhaps also wrapped in a #ifdef DEBUG ... #endif to avoid shipping it).