如何在每次使用 Xcode 7 UI 测试后重置应用程序数据?

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

Apple 在 Xcode 7 中引入了新的 UI 测试,但每当测试启动应用程序时我都会遇到困难,它从应用程序之前拥有的数据开始。这意味着测试不能独立并且会受到其他测试的影响。

无法访问用户默认值和其他数据,因为正在测试的应用程序 运行 无法访问测试应用程序的捆绑包。脚本也没有问题,因为它们可以在测试之前或之后 运行。并且没有办法在每个测试套件之前在 iOS 到 运行 脚本上执行 NSTask。

有没有办法在每个测试套件之前重置应用程序数据?

不是直接的方式。但是有一些解决方法。

XCUIApplication 可以设置可以改变应用程序行为的命令行参数和环境变量。

您的 main.m 文件的一个简单示例:

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]));
    }
}

并在 -[XCTestCase setUp] 中添加:

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

如果在 application:didFinishLaunchingWithOptions: 中为 UITests 准备应用程序对您来说没问题,那么您可以执行以下操作:

在你测试的setUp()方法中class扩展XCTestCase添加以下代码:

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

然后,在 application:didFinishLaunchingWithOptions: 中,您可以使用以下代码检查标志:

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
}

当然,如果您愿意的话。

注意:不是将 "1" 设置为 "UITESTS" 标志的参数,您可以为不同的测试用例指定不同的值 - 甚至测试方法(但在这种情况下,您应该启动应用程序来自测试方法,而不是 setUp())

注意 2:我建议将处理标志的代码包装到 #if DEBUG 块中。

我必须使用一些私有 headers 来访问 springboard 和设置应用程序来重置应用程序数据。

首先,我添加了一个 运行 脚本阶段,以便在测试开始时将其删除:

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

然后我使用我写的解决方案 here 删除它,使用在 tearDown 调用上运行的测试脚本在每次测试后重置它。

就我而言,我还需要重置权限。并且有一个选项可以删除您的应用程序并重置系统权限,只需让测试删除应用程序并导航至设置即可。

已在此 S.O 中回答。线程:Is there a way to reset the app between tests in Swift XCTest UI in Xcode 7?