繁体   English   中英

如何使用模拟器在XCUITest中以编程方式清除NSUserDefaults

[英]How to clear NSUserDefaults programmatically in XCUITest using Simulator

我已经阅读了几个与此相关的答案,他们建议执行以下操作之一,但这些选项对我不起作用。 我有一个XCUITest,我试图在运行其余的XCUITest之前清除标准用户默认值。 目前我的测试应用程序有一个调用此代码的按钮。 我也尝试直接从XCUITest中调用此代码(我不确定这是否可以使用或者是否需要在应用程序内运行)。

NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];

我也试过逐个删除:

[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"MyKey1"];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"MyKey2"];

我还尝试了上面的每个方法,然后是同步调用:

[[NSUserDefaults standardUserDefaults] synchronize];

下次我从NSUserDefaults读取@“MyKey1”时,它仍然具有旧值并且尚未被删除。

在模拟器中运行XCUITest时,有没有办法以编程方式从NSUserDefaults中删除对象? 这些都是自动化测试,所以我不能总是手动点击xcode中的“重置内容和设置”。

谢谢!

通过在测试运行应用程序之前设置UserDefaults值(而不是之后),有几种方法可以解决您的问题。

解决方案#1

使用某些键模拟UserDefaults值launchArguments

func testExample() {
    let app = XCUIApplication()
    app.launchArguments += ["-keepScreenOnKey", "YES"]
    app.launch()
}

请注意 keepScreenOnKey键之前的keepScreenOnKey 减号表示它应该将下一个启动参数值作为该UserDefaults键的值。

解决方案#2(如果解决方案#1不起作用)

如果您使用的是SwiftyUserDefaults库,则以前的解决方案可能无效。 在这种情况下,有一个优雅的解决方案:如果应用程序在UI测试下运行,则从应用程序中清除所有UserDefaults数据。 应用程序如何知道它是否在UI测试下运行? 通过传递启动参数消息,如下所示:

override func setUp() {
    super.setUp()
    app.launchArguments += ["UI-Testing"]
}

然后,在AppDelegate.swift检查应用程序是否在UI-Testing下运行并删除所有UserDefaults数据(就像您一样):

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

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

        return true
    }

    static var isUITestingEnabled: Bool {
        get {
            return ProcessInfo.processInfo.arguments.contains("UI-Testing")
        }
    }

    private func setStateForUITesting() {
        if AppDelegate.isUITestingEnabled {
            UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
        }
    }
}

解决方案#3(如果解决方案#2不够)

但是,如果UI测试需要解决方案#2设置的默认状态以外的状态怎么办? Bools默认为false ,Integers为0 ,字符串为"" ,但如果Bool键需要true ,该怎么办?

做这样的事情:

func testExample() {
    app.launchEnvironment["UI-TestingKey_keepScreenOn"] = "YES"
    app.launch()
}

然后在AppDelegate.swift文件中:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    static let uiTestingKeyPrefix = "UI-TestingKey_"

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

        if AppDelegate.isUITestingEnabled {
            setUserDefaults()
        }

        return true
    }

    static var isUITestingEnabled: Bool {
        get {
            return ProcessInfo.processInfo.arguments.contains("UI-Testing")
        }
    }

    private func setUserDefaults() {
        for (key, value)
            in ProcessInfo.processInfo.environment
            where key.hasPrefix(AppDelegate.uiTestingKeyPrefix) {
            // Truncate "UI-TestingKey_" part
            let userDefaultsKey = key.truncateUITestingKey()
            switch value {
            case "YES":
                UserDefaults.standard.set(true, forKey: userDefaultsKey)
            case "NO":
                UserDefaults.standard.set(false, forKey: userDefaultsKey)
            default:
                UserDefaults.standard.set(value, forKey: userDefaultsKey)
            }
        }
    }
}

extension String {
    func truncateUITestingKey() -> String {
        if let range = self.range(of: AppDelegate.uiTestingKeyPrefix) {
            let userDefaultsKey = self[range.upperBound...]
            return String(userDefaultsKey)
        }
        return self
    }
}

请注意,此示例仅适用于Bool和String键。 如果你需要更多的可伸缩性,应该修改switch命令以某种方式检查值是Integer还是Double或Any其他值,但总体思路就在这里。

编辑:从SwiftyUserDefaults 版本4.0.0-beta.1开始 ,使用解决方案#2和#3的原因似乎不再有效,因为他们通过启动参数添加了对设置值的支持。 但是,我不得不承认我之前没有测试过这个版本的SwiftyUserDefaults库,所以我会在这里保留两个解决方案。

通过UI测试,应用程序作为单独的进程运行。 您需要调用方法从应用程序本身清除NSUserDefaults。

我们的UI测试在启动应用程序时向应用程序传递了res​​etNSUserDefaults标志。 然后,应用程序会在启动过程的早期清除NSUserDefaults。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM