How do I reset the application data after each test with Xcode 7 UI Testing?

百般思念 提交于 2019-11-27 00:55:23

问题


Apple introduced in Xcode 7 new UI Testing but I have a struggle whenever the tests launches the app, it starts with data that the application had before. It means tests cannot be independent and can be influenced by other tests.

It is not possible to access user defaults and other data because the application that is running tests has no access to the bundle of the tested application. Scripts are also out of question because they can be run before or after testing. And there is no way how to execute NSTask on iOS to run a script before each test suite.

Is there a way how do reset the application data before each test suite?


回答1:


Not in a straight forward manner. But there are some workarounds.

The XCUIApplication can set command line arguments and environment variables that can alter your application’s behavior.

A simple example of your main.m file:

int main(int argc, char * argv[]) {
#if DEBUG
    // Reset all data for UI Testing
    @autoreleasepool {
        for (int i = 1; i < argc; ++i) {
            if (0 == strcmp("--reset-container", argv[i])) {
                NSArray *folders = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
                NSFileManager *fm = [[NSFileManager alloc] init];
                for (NSString *path in folders) {
                    [fm removeItemAtPath:path error:nil];
                }
                // Also remove documents folder if necessary...
            }
        }
    }
#endif
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil,
                                 NSStringFromClass([AppDelegate class]));
    }
}

And in -[XCTestCase setUp] add:

XCUIApplication *app = [[XCUIApplication alloc] init];
app.launchArguments = @[@"--reset-container"];
[app launch];



回答2:


If preparing the app for UITests inside application:didFinishLaunchingWithOptions: is ok in your case, then you can do the following:

In setUp() method of your test class extending XCTestCase add following code:

let application = XCUIApplication()
application.launchEnvironment = ["UITESTS":"1"]
application.launch()

Then, in application:didFinishLaunchingWithOptions: you can check for the flag using following code:

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {

    let env = ProcessInfo.processInfo.environment
    if let uiTests = env["UITESTS"], uiTests == "1" {
        // do anything you want
    }
    // further set up code
}

Of course if that is an option for you.

NOTE: Instead of setting "1" as argument for "UITESTS" flag, you can specify different values for different test cases - or even test methods (but in such case, you should launch the application from test method, not setUp())

NOTE 2: I suggest wrapping the code dealing with the flag into #if DEBUG block.




回答3:


I got to reset the application data using some private headers to access to the springboard and the settings app.

First I added a Run script phase to remove it when the tests starts:

/usr/bin/xcrun simctl uninstall booted com.mycompany.bundleId

And after that I use the solution I wrote here to remove it using a test script that runs on the tearDown calls to reset it after every test.




回答4:


In my case I required to also reset permissions. And there's an option to delete your app and reset system permissions just making the test delete the app and navigate to settings.

Already answered in this S.O. thread: Is there a way to reset the app between tests in Swift XCTest UI in Xcode 7?



来源:https://stackoverflow.com/questions/32351149/how-do-i-reset-the-application-data-after-each-test-with-xcode-7-ui-testing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!