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
相关产品推荐
相关产品推荐

