You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xcode UI测试无法点击表单内Menu按钮的解决方法咨询

问题

在Xcode的UI测试中,无法点击表单中的Menu按钮,但可正常点击表单内的常规按钮。此前在模拟器中观察到,UI测试会点击表单行的中心位置,该方式对常规按钮有效,但对Menu按钮无效。在Xcode的SwiftUI预览中测试发现,Menu按钮需要精准点击按钮本身,而常规按钮点击表单行任意位置均可触发。(目前未知原因导致即使开启模拟器“显示单次触摸”设置,也无法再看到UI测试的触摸操作。)

请问如何在UI测试中打开表单内的Menu按钮?

UI代码

struct ContentView: View {
    @State private var label1 = "Menu 1"
    @State private var label2 = "Menu 2"

    var body: some View {
        NavigationStack {
            Form {
                LabeledContent("Menu 1") {
                    Button(label1) {
                        label1 = "Menu 1 tapped"
                    }
                    .accessibilityIdentifier("menu1")
                }
                LabeledContent("Menu 2") {
                    Menu(label2) {
                        Button("Button") {
                            
                        }
                        .accessibilityIdentifier("button")
                    }
                    .accessibilityIdentifier("menu2")
                }
            }
        }
    }
}

#Preview {
    ContentView()
}

测试代码(原代码)

final class problemUITests: XCTestCase {

    func testExample() throws {
        // UI tests must launch the application that they test.
        let app = XCUIApplication()
        app.launch()
        
        app.collectionViews.element(boundBy: 0).buttons["menu1"].tap()
        app.collectionViews.element(boundBy: 0).buttons["menu2"].tap()
        app.collectionViews.element(boundBy: 0).buttons["button"].tap()
    }
}
解决方案

1. 精准定位Menu按钮的可点击区域

Menu按钮的有效点击范围比常规按钮更窄,UI测试默认的中心点击可能落在按钮外部。可以通过获取按钮的frame,计算并点击其实际可触发的位置:

func testExample() throws {
    let app = XCUIApplication()
    app.launch()
    
    // 常规按钮正常点击
    app.collectionViews.element(boundBy: 0).buttons["menu1"].tap()
    
    // 处理Menu按钮:定位按钮右侧有效区域
    let menu2Button = app.collectionViews.element(boundBy: 0).buttons["menu2"]
    let menuFrame = menu2Button.frame
    // 计算按钮右侧的点击点(避开行的中心区域)
    let tapPoint = CGPoint(x: menuFrame.maxX - 10, y: menuFrame.midY)
    // 转换为测试坐标系统的点并点击
    let normalizedPoint = app.coordinate(withNormalizedOffset: .zero).withOffset(tapPoint)
    normalizedPoint.tap()
    
    // 点击Menu内的子按钮
    app.collectionViews.element(boundBy: 0).buttons["button"].tap()
}

2. 扩大Menu的可点击区域(UI代码调整)

如果允许修改业务代码,可以给Menu添加contentShape,将可点击范围扩大至父视图区域,让UI测试的中心点击也能触发:

Menu(label2) {
    Button("Button") {
        
    }
    .accessibilityIdentifier("button")
}
.accessibilityIdentifier("menu2")
.contentShape(Rectangle()) // 扩大可点击区域至LabeledContent的右侧容器范围

修改后,原测试代码中的menu2Button.tap()即可正常触发Menu。

3. 用短长按替代普通点击

尝试使用press(forDuration:)方法,短长按操作有时能绕过点击位置的限制,成功唤起Menu:

app.collectionViews.element(boundBy: 0).buttons["menu2"].press(forDuration: 0.1)

内容的提问来源于stack exchange,提问作者Nickkk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 14:12:40