测试前如何重置@AppStorage?

问题描述 投票:0回答:2

我试图在测试前清除用户默认值,但

removePersistentDomain
不起作用。

override func setUpWithError() throws {
        // Put setup code here. This method is called before the invocation of each test method in the class.
        if let bundleID = Bundle.main.bundleIdentifier {
            print("BUNDLE", bundleID)
            print("UserDefaults", UserDefaults.standard.dictionaryRepresentation().keys.description)
            
            UserDefaults.standard.removePersistentDomain(forName: "com.example.App")
            UserDefaults.standard.removePersistentDomain(forName: bundleID) // "com.example.AppUITests"
            
            print("UserDefaults", UserDefaults.standard.dictionaryRepresentation().keys.description)
        }

        // In UI tests it is usually best to stop immediately when a failure occurs.
        continueAfterFailure = false

        // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
    }

我尝试打印按键,但我定义的按键均未显示。

UserDefaults ["AppleLanguages", "AddingEmojiKeybordHandled", "AKLastIDMSEnvironment", "AppleKeyboardsExpanded", "ApplePasscodeKeyboards", "XCTEmitOSLogs", "NSInterfaceStyle", "AppleLanguagesDidMigrate", "XCTTelemetryFlushTimeout", "NSLanguages", "XCTDisableTelemetryLogging", "PKLogNotificationServiceResponsesKey", "AppleKeyboards", "AppleLanguagesSchemaVersion", "AKLastLocale", "XCUIApplicationCrashReportTimeoutDefault", "XCTIDEConnectionTimeout"]
UserDefaults ["XCTEmitOSLogs", "AddingEmojiKeybordHandled", "AKLastLocale", "NSLanguages", "AppleLanguagesDidMigrate", "AppleKeyboards", "NSInterfaceStyle", "XCUIApplicationCrashReportTimeoutDefault", "XCTDisableTelemetryLogging", "AppleLanguages", "ApplePasscodeKeyboards", "AppleLanguagesSchemaVersion", "PKLogNotificationServiceResponsesKey", "XCTTelemetryFlushTimeout", "AppleKeyboardsExpanded", "XCTIDEConnectionTimeout", "AKLastIDMSEnvironment"]

应用程序存储的密钥似乎存储在其他地方。 @AppStorage使用什么域名/套件名称?

编辑:

如果我运行测试,则会显示保存的值

@AppStorage("someString")
,但它不是
UserDefaults.standard.dictionaryRepresentation()
的一部分。

func testExample() throws {
    // UI tests must launch the application that they test.
    let app = XCUIApplication()
    app.launch()

    // Use XCTAssert and related functions to verify your tests produce the correct results.
    
    sleep(10)
}

编辑2: 我创建了一个包含测试的新项目。

import SwiftUI

struct ContentView: View {
    
    @AppStorage("test") var test = "Test"
    var body: some View {
        VStack {
            Text(test)
            Button(action: {
                test = "New value"
            }) {
                Text("Change value")
            }
            Button(action: {
                if let bundleID = Bundle.main.bundleIdentifier{
                    UserDefaults.standard.removePersistentDomain(forName: bundleID)
                }
            }){
                Text("Reset storage")
            }
        }
    }
}
import XCTest

final class TestStorageUITests: XCTestCase {

    override func setUpWithError() throws {
        // Put setup code here. This method is called before the invocation of each test method in the class.
        for e in UserDefaults.standard.dictionaryRepresentation(){
            print("UserDefault", e.key, e.value)
        }
        
        // In UI tests it is usually best to stop immediately when a failure occurs.
        continueAfterFailure = false

        // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
    }

    override func tearDownWithError() throws {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
    }

    func testExample() throws {
        // UI tests must launch the application that they test.
        let app = XCUIApplication()
        app.launch()

        // Use XCTAssert and related functions to verify your tests produce the correct results.
        sleep(10)
    }
}

我尝试从应用程序中清除用户默认设置。 UI 不会刷新,但打印时我确实看到了

UserDefault test New value
dictionaryRepresentation
。重新启动应用程序后,将显示值“Test”。

如果我通过测试来做到这一点,它就不起作用。

func testExample() throws {
        // UI tests must launch the application that they test.
        let app = XCUIApplication()
        app.launch()

        app.buttons["Change value"].tap()
        
        for e in UserDefaults.standard.dictionaryRepresentation(){
            print("UserDefault2", e.key, e.value)
        }

        app.buttons["Reset storage"].tap()
        
        for e in UserDefaults.standard.dictionaryRepresentation(){
            print("UserDefault3", e.key, e.value)
        }
    }
UserDefault XCTDisableTelemetryLogging 0
UserDefault AddingEmojiKeybordHandled 1
UserDefault NSInterfaceStyle macintosh
UserDefault AKLastIDMSEnvironment 0
UserDefault NSLanguages (
UserDefault PKLogNotificationServiceResponsesKey 0
UserDefault AppleLanguagesDidMigrate 20E247
UserDefault AppleKeyboards (
UserDefault XCTEmitOSLogs 0
UserDefault XCTIDEConnectionTimeout 600
UserDefault AppleKeyboardsExpanded 1
UserDefault AppleLanguagesSchemaVersion 3000
UserDefault XCTTelemetryFlushTimeout 10
UserDefault ApplePasscodeKeyboards (
UserDefault AppleLanguages (
UserDefault AKLastLocale en_US
UserDefault XCUIApplicationCrashReportTimeoutDefault 20
UserDefault2 AppleLanguages (
UserDefault2 XCTDisableTelemetryLogging 0
UserDefault2 PKLogNotificationServiceResponsesKey 0
UserDefault2 AppleKeyboards (
UserDefault2 NSLanguages (
UserDefault2 AKLastIDMSEnvironment 0
UserDefault2 AppleKeyboardsExpanded 1
UserDefault2 ApplePasscodeKeyboards (
UserDefault2 NSInterfaceStyle macintosh
UserDefault2 XCTIDEConnectionTimeout 600
UserDefault2 AppleLanguagesSchemaVersion 3000
UserDefault2 AKLastLocale en_US
UserDefault2 XCUIApplicationCrashReportTimeoutDefault 20
UserDefault2 XCTEmitOSLogs 0
UserDefault2 AppleLanguagesDidMigrate 20E247
UserDefault2 XCTTelemetryFlushTimeout 10
UserDefault2 AddingEmojiKeybordHandled 1
UserDefault3 PKLogNotificationServiceResponsesKey 0
UserDefault3 AKLastIDMSEnvironment 0
UserDefault3 XCTEmitOSLogs 0
UserDefault3 NSInterfaceStyle macintosh
UserDefault3 AppleLanguages (
UserDefault3 AppleLanguagesDidMigrate 20E247
UserDefault3 NSLanguages (
UserDefault3 XCTDisableTelemetryLogging 0
UserDefault3 AddingEmojiKeybordHandled 1
UserDefault3 AppleKeyboardsExpanded 1
UserDefault3 XCTTelemetryFlushTimeout 10
UserDefault3 AppleKeyboards (
UserDefault3 AKLastLocale en_US
UserDefault3 XCTIDEConnectionTimeout 600
UserDefault3 XCUIApplicationCrashReportTimeoutDefault 20
UserDefault3 AppleLanguagesSchemaVersion 3000
UserDefault3 ApplePasscodeKeyboards (

但是,按“重置存储”按钮会刷新 UI。

swift xcode-ui-testing
2个回答
0
投票

UI 测试在单独的进程中运行,因此它正在访问不同的

UserDefaults
。启动 UI 测试时,会出现一个新的应用程序图标“TestStorageUITests”,它不执行任何操作,但测试仍然在实际应用程序“TestStorage”中运行。 (我猜测测试以“TestStorageUITests”开始,并在执行时切换到“TestStorage”。)
如果至少能够在设置代码中访问应用程序数据就好了,但一种方法是在启动应用程序时

发送标志

,并从 app.launch() 调用

removePersistentDomainForName
App

let app = XCUIApplication()
app.launchArguments += ["UI-Testing"]
app.launch()


0
投票

我使用函数 is_tc_accepted() 来切换条款和条件的显示。

@main struct SomeApp: App { init(){ if ProcessInfo.processInfo.arguments.contains("UI-Testing"){ if let bundleID = Bundle.main.bundleIdentifier { UserDefaults.standard.removePersistentDomain(forName: bundleID) } } } var body: some Scene { WindowGroup { ContentView() } } }

假设我想在 TCs.tc_version = 1.2 时测试应用程序的行为,我将提供以下命令来执行 UI 测试

@AppStorage("configuration_tcAcceptedVersion") private var tcVersion: Double = 0.0 var is_tc_accepted: Bool { return tcVersion == TCs.tc_version } func TCCloseButtonClicked() { tcVersion = TCs.tc_version }

这将导致“configuration_tcAcceptedVersion”参数设置为只读。条款和条件出现,但“TCCloseButtonClicked()”按钮处理程序根本不会执行任何操作,因为“tcVersion”变量是只读的。

我真的很高兴我找到了传递重置 @AppStorage 参数的选项,这样我就可以通过 UI 测试首次启动应用程序。

© www.soinside.com 2019 - 2024. All rights reserved.