SwiftUI 切换在 UI 测试中未切换

Mar*_*son 10 xcode swift xcode-ui-testing swiftui

我无法进行 UI 测试来切换 SwiftUI 表单中的 Toggle。似乎app.switches[*name*].tap()没有什么作用。还有其他人经历过吗?有想法吗?

下面的代码是该问题的演示。这是一个带有四个开关的简单形式,可根据开关位置生成一个 int 值。

我有以下 SwiftUI 视图:

struct ContentView: View {
    
    @State var sw1: Bool = false
    @State var sw2: Bool = false
    @State var sw3: Bool = false
    @State var sw4: Bool = false
    
    
    var valueString: String {
        var ret: Int = 0
        if sw1 {
            ret = ret + 1
        }
        if sw2 {
            ret = ret + 2
        }
        if sw3 {
            ret = ret + 4
        }
        if sw4 {
            ret = ret + 8
        }
        return String(ret)
    }
    
    var body: some View {
        NavigationStack {
            Form {
                Section("Binary switches"){
                    Toggle("1", isOn: $sw1)
                        .accessibilityIdentifier("sw1")
                    Toggle("2", isOn: $sw2)
                        .accessibilityIdentifier("sw2")
                    Toggle("4", isOn: $sw3)
                        .accessibilityIdentifier("sw3")
                    Toggle("8", isOn: $sw4)
                        .accessibilityIdentifier("sw4")
                }
                Section("Value") {
                    Text(valueString)
                        .accessibilityIdentifier("value")
                        .accessibilityValue(valueString)
                }
            }
            .navigationTitle("Test Form")
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

以及以下 UI 测试代码:

func testRandomSwitches() throws {
    let app = XCUIApplication()
    app.launch()
    
    // Get the binary switches
    let sw1 = app.switches["sw1"]
    let sw2 = app.switches["sw2"]
    let sw3 = app.switches["sw3"]
    let sw4 = app.switches["sw4"]
    
    // randomly switch on some of the switches
    let randomOnes = [sw1, sw2, sw3, sw4].map { _ in Bool.random() }
    if randomOnes[0] { sw1.tap() }
    if randomOnes[1] { sw2.tap() }
    if randomOnes[2] { sw3.tap() }
    if randomOnes[3] { sw4.tap() }
    
    // calculate the expected value
    let expectedValue = randomOnes.enumerated()
        .filter { $0.element }
        .map { 1 << $0.offset }
        .reduce(0, +)
    
    // get the value text and assert that it matches the expected value
    let value = app.staticTexts["value"].value as? String ?? ""
    XCTAssertEqual(value, String(expectedValue))
}

Run Code Online (Sandbox Code Playgroud)

当我运行此测试时,开关永远不会切换,并且值字符串始终读取“0”。UITest 代码在XCTAssertEqual(value, String(expectedValue)). 我不确定我做错了什么。

如果我尝试记录切换点击,我总是收到错误“时间戳事件匹配错误:无法找到匹配元素”。

谁能帮我弄清楚为什么我的 UI 测试中没有切换开关?

Mar*_*son 23

弄清楚了。看来我需要访问交换机中的第一个交换机。真奇怪。但我猜 UI 测试很奇怪。如果有人能得到一个不那么棘手的解决方案,我们将不胜感激。

非工作代码:

sw1.tap()
Run Code Online (Sandbox Code Playgroud)

工作代码:

sw1.switches.firstMatch.tap()
Run Code Online (Sandbox Code Playgroud)

  • 哇,这也为我做到了......谢谢!永远不会明白这一点! (3认同)