如何在XCTest中提取SwiftUI Menu Picker的真实选项?
你遇到的问题是因为使用.menu样式的Picker时,点击弹出菜单后,原来的Picker按钮(显示"Choose an option, Option 1")仍然停留在界面上,而你遍历的是全局的app.buttons,所以把这个按钮也包含进了结果里。下面是几种可行的解决办法:
方法1:直接定位菜单内的选项(最推荐)
SwiftUI的MenuPicker弹出的菜单会被归类到XCUIApplication().menus层级下,直接获取菜单容器内的按钮,就能只拿到真正的选项:
修改测试代码中获取选项的部分:
// Tap the picker to bring up the menu. picker.tap() // 定位弹出的菜单,只取菜单内的按钮 let menu = app.menus.firstMatch let pickerItems = menu.buttons.allElementsBoundByIndex // Extract menu choices. var menuChoices: [String] = [] for item in pickerItems { menuChoices.append(item.label) }
这样收集到的menuChoices就只会是["Option 1", "Option 2", "Option 3", "Option 4"],不会包含额外的条目。
方法2:过滤不符合预期的条目
如果不想依赖菜单层级,也可以直接过滤掉包含Picker标题的条目,或者只保留预期的选项:
首先在测试代码里定义和应用一致的预期选项数组:
let expectedOptions = ["Option 1", "Option 2", "Option 3", "Option 4"]
然后在收集选项时过滤:
// Extract menu choices and filter let menuChoices = pickerItems .map(\.label) .filter { expectedOptions.contains($0) }
或者直接过滤掉包含Picker标题的条目:
let menuChoices = pickerItems .map(\.label) .filter { !$0.contains("Choose an option") }
方法3:通过辅助标识精准定位选项
更可靠的方式是给每个Picker选项设置唯一的辅助标识,避免依赖文本内容:
修改SwiftUI应用代码中的Picker选项部分:
ForEach(options, id: \.self) { option in Text(option) .accessibilityIdentifier("picker-option-\(option)") }
然后在测试代码中通过标识匹配获取选项:
// Tap the picker to bring up the menu. picker.tap() // 匹配所有以"picker-option-"开头的按钮 let pickerItems = app.buttons.matching( identifier: NSPredicate(format: "BEGINSWITH %@", "picker-option-") ).allElementsBoundByIndex // 提取选项文本 let menuChoices = pickerItems.map { $0.label }
内容的提问来源于stack exchange,提问作者Pabtuz
相关产品推荐
相关产品推荐

