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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32351149/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 07:45:25  来源:igfitidea点击:

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

iosxcodexcode7ui-testingxcode-ui-testing

提问by Tomá? Linhart

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.

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

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.

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

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

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

采纳答案by Mats

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

不是直截了当的。但是有一些解决方法。

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

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

A simple example of your main.mfile:

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

And in -[XCTestCase setUp]add:

-[XCTestCase setUp]补充说:

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

回答by manicaesar

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

如果application:didFinishLaunchingWithOptions:在您的情况下为 UITests 准备应用程序是可以的,那么您可以执行以下操作:

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

setUp()您的测试类扩展的方法中XCTestCase添加以下代码:

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

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

然后,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
}

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

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

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

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

回答by odm

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

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

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

之后,我使用我在此处编写的解决方案使用测试脚本将其删除,该脚本tearDown在每次测试后在调用时运行以重置它。

回答by Eli Kohen

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?

已经在这个 SO 线程中回答了:有没有办法在 Xcode 7 中的 Swift XCTest UI 中的测试之间重置应用程序?