How to access launchEnvironment and launchArguments set in XCUIApplication, running UI tests in XCode?

25,271

Solution 1

If you set launchArguments in a UI Test (Swift):

let app = XCUIApplication()
app.launchArguments.append("SNAPSHOT")
app.launch()

Then read them in your App using:

swift 2.x:

if NSProcessInfo.processInfo().arguments.contains("SNAPSHOT") {
   // Do snapshot setup
}

Swift 3.0

if ProcessInfo.processInfo.arguments.contains("SNAPSHOT") {
}

To set environment variables, use launchEnvironment and NSProcessInfo.processInfo().environment, respectively, instead.

Solution 2

Building on Joey C.'s answer, I wrote a small extension to avoid using raw strings in the app. This way you avoid any typo issue and get autocompletion.

extension NSProcessInfo {
    /**
     Used to recognized that UITestings are running and modify the app behavior accordingly

     Set with: XCUIApplication().launchArguments = [ "isUITesting" ]
     */
    var isUITesting: Bool {
        return arguments.contains("isUITesting")
    }

    /**
     Used to recognized that UITestings are taking snapshots and modify the app behavior accordingly

     Set with: XCUIApplication().launchArguments = [ "isTakingSnapshots" ]
     */
    var isTakingSnapshots: Bool {
        return arguments.contains("isTakingSnapshots")
    }
}

This way you can use

if NSProcessInfo.processInfo().isUITesting {
   // UITesting specific behavior,
   // like setting up CoreData with in memory store
}

Going further, the various arguments should probably go into an enum that could be reused in the UITest when setting the launchArguments.

Solution 3

It's also interesting to note that arguments passed to XCUIApplication.launchArguments are also available from UserDefaults.

In your XCTestCase

let app = XCUIApplication()
app.launchArguments.append("-ToggleFeatureOne")
app.launchArguments.append("true")
app.launch()

In your target under test

UserDefaults.standard.bool(forKey: "ToggleFeatureOne") // returns true

From here you could create extensions on UserDefaults to provide handy run time toggles.

This is the same mechanism the Xcode schemes "arguments passed on launch" uses. Launch arguments and their effect on UserDefaults are documented under Preferences and Settings Programming Guide.

Solution 4

Here is example with launchArguments and Objective-C:

if ([[NSProcessInfo processInfo].arguments containsObject:@"SNAPSHOT"]) {
        //do snapshot;
}

Swift:

    let arguments = ProcessInfo.processInfo.arguments
    if arguments.contains("SNAPSHOT") {
        //do snapshot
    }

Solution 5

For launch arguments, pass them as two separate arguments:

let app = XCUIApplication()  
app.launchArguments.append("-arg")  
app.launchArguments.append("val")  
app.launch()

Taken from here.

Share:
25,271
bogen
Author by

bogen

CTO @ Beining & Bogen

Updated on March 06, 2020

Comments

  • bogen
    bogen about 4 years

    I've tried setting attributes in the XCUIApplication instance, in my UI Tests setUp()

    let app = XCUIApplication()
    app.launchEnvironment = ["testenv" : "testenvValue"]
    app.launchArguments = ["anArgument"]
    app.launch()
    

    in didFinishLaunch I've tried to show these on screen when I run my UITests

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        if launchOptions != nil {
            for (key, value) in launchOptions! {  
                let alertView = UIAlertView(title: key.description, message: value.description, delegate: nil, cancelButtonTitle: "ok")
                alertView.show()
            }
        }
    

    But I can't seem to be able to find the arguments and environment I set. Anyone know how to get a hold of them?

  • drekka
    drekka about 8 years
    Under Xcode 7.3 this does not seem to be working. I've tried set launchArguments and then read them straight back. I always get back and empty array. Even if I do it on the very next line. Looks like they may be broken. Same for launchEnvironment.
  • EricS
    EricS about 8 years
    Make sure you have only one XCUIApplication instance and call launch after setting launchArguments.
  • Trevis Thomas
    Trevis Thomas about 7 years
    This is the answer than actually solves the problem and explains why.
  • BadmintonCat
    BadmintonCat over 6 years
    Hi! Where do I find a list of al supported launch arguments?
  • AechoLiu
    AechoLiu over 6 years
    When Record UI Test in Xcode, it doesn't run setUp(). It misleads me the above codes not working. But run the UI test again (not Record UI Test mode), it works.
  • Nick
    Nick over 5 years
    In case any one else is banging their head as I was because it still wasn't working, the Build Configuration must also be set to Debug. If set to Release it will have empty launch arguments.