How do I reset the application data after each test with Xcode 7 UI Testing?
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];
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.
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.