How to Access Launchenvironment and Launcharguments Set in Xcuiapplication, Running UI Tests in Xcode

launchArguments in UITesting in Xcode 7.3 not working

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).

How do I keep the app open between UITests in Xcode

In your setUp() method, remove [[[XCUIApplication alloc] init] launch]; and put it into the first test you will be performing.

For eg.,

If you have tests: testUI(), testUIPart2(), testUIPart3(), etc., and it runs in this order, put [[[XCUIApplication alloc] init] launch]; into the first line of testUI() and no where else.

What is the correct way to open a file from line arguments in an NSDocument application in Swift?

1) what is the correct way to pass mock data for UI testing of an NSDocument based application?

What I do is the following:

1) To open a new document I call makeUntitledDocument(ofType typeName: String). There is no need to override it at all. You can then set up the document as you wish with the returned value of this API.

2) To open a previously saved document I call indeed openDocument(withContentsOf:display:completionHandler:)

Using pseudo-code would be something like this, where you can pass any URL with the mock data:

func openDocument(itemData:ItemData) {
let controller = NSDocumentController.shared
controller.openDocument(withContentsOf: itemData.url, display: true)
{ (_, _, error:Error?) in
if error != nil {
handleError(.unableToOpenDocument(itemData.url))
}
}
}

Once again, there is no need to override openDocument(withContentsOf:display:completionHandler:).

2) what is the correct way to open a file on launch of an application using a line argument?

I would use a bash script for that using:

open -a $APP_PATH $DOCUMENT_PATH

This will mimic what the Finder does, but if you don't like that option, then you can always try what they propose in the answers to this question here.

Is it possible to open a screen directly in XCUITest?

As far as I know, you can't go directly to the second screen using XCUITest Framework. Anyway, documentation states:

UI testing exercises your app's UI in the same way that users do without access to your app's internal methods, functions, and variables. This enables your tests to see the app the same way a user does, exposing UI problems that users encounter.

Which means that if user of your app can't reach the second screen directly, why could your UI tests.

I know it's time consuming to wait to go to the second screen when you run your tests, but you can bypass writing it for every test. To write it only once, in your XCTestCase class write a function where you implement calling a second screen and call that function in setUp() method. Then, the process of skipping the first screen will be called every time you run a test because setUp() method is called before every test run.

EDIT

After reading your comment, I could think of one hacky solution. You can communicate with your app from your tests using Launch Environment and/or Launch Arguments. So, in your XCTestCase class, set up argument and environment:

class ForgotPasswordUITest: XCTestCase {
let app = XCUIApplication()

override func setUp() {
app.launchArguments += ["UI-TESTING"]
app.launchEnvironment["pageToGo"] = "forgotPassword"
app.launch()
}
}

Then, in your ViewController, write these computed properties:

var isUiTestingEnabled: Bool {
get {
return ProcessInfo.processInfo.arguments.contains("UI-TESTING")
}
}

var shouldShowForgotPassword: Bool {
get {
return ProcessInfo.processInfo.environment["pageToGo"] == "forgotPassword"
}
}

var shouldShowHelpScreen: Bool {
get {
return ProcessInfo.processInfo.environment["pageToGo"] == "helpScreen"
}
}

And in viewDidLoad() method, you can have something like this:

    if isUiTestingEnabled {
if shouldShowForgotPassword {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let secondViewController = storyboard.instantiateViewController(withIdentifier: "ForgotPasswordViewController")
self.present(secondViewController, animated: true, completion: nil)
} else if shouldShowHelpScreen {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let secondViewController = storyboard.instantiateViewController(withIdentifier: "HelpScreenViewController")
self.present(secondViewController, animated: true, completion: nil)
}
}

Note: this is a really dirty hack and it is not recommended way of writing UI tests.

Xcode UI Test environment variables not being passed from Scheme

Launch arguments and launch environments provided in the scheme editor are passed only to UI test runner. You can read those values only in UI test classes.

If you want to pass those values to the application itself you have to do it in the code:

let app = XCUIApplication()
app.launchArguments = ["amandaArgument"]
app.launchEnvironment = ["AMANDA_UI_TESTING": "Value"]
app.launch()


Related Topics



Leave a reply



Submit