iOS UI测试:如何访问NavigationStack中的搜索栏?
问题根源
- 标识符绑定错误:你将
accessibilityIdentifier附加到了NavigationStack容器视图上,而非searchable生成的搜索输入框本身。app.searchFields只会匹配类型为搜索输入框的元素,NavigationStack不属于这类元素,因此无法找到目标。 - 搜索栏默认隐藏:
searchable修饰符生成的搜索栏默认处于折叠隐藏状态,直接查找会因元素未显示而失败。
修正方案
1. 调整业务代码,给搜索栏正确设置标识符
将accessibilityIdentifier直接绑定到搜索输入框上,而非容器视图,有两种实现方式:
方式一:自定义搜索栏视图
通过searchable的闭包自定义搜索输入框,并设置标识符:
var body: some View { NavigationStack { List { // 业务列表元素 } } .searchable(text: $searchText) { TextField("搜索", text: $searchText) .accessibilityIdentifier("SearchField") } }
方式二:给默认搜索栏绑定标识符
如果使用系统默认搜索栏,可调整可访问性层级确保标识符关联到搜索栏:
var body: some View { NavigationStack { List { // 业务列表元素 } } .searchable(text: $searchText) .accessibilityElement(children: .contain) .accessibilityIdentifier("SearchField") }
2. 修正UI测试代码,先触发搜索栏显示
默认状态下搜索栏隐藏,需先触发显示再进行操作:
override func setUpWithError() throws { continueAfterFailure = false let app = XCUIApplication() app.launch() // 触发搜索栏显示:点击导航栏上的搜索折叠按钮 app.navigationBars.buttons["Search"].tap() // 若搜索栏通过下拉列表触发,可替换为: // app.tables.firstMatch.swipeDown() // 验证搜索栏存在 let searchField = app.searchFields["SearchField"] XCTAssertTrue(searchField.exists, "搜索栏应该存在") // 输入搜索文本 searchField.tap() searchField.typeText("测试搜索内容") // 执行搜索:点击键盘上的搜索按钮 app.keyboards.buttons["Search"].tap() // 或直接输入回车触发: // searchField.typeText("\r") }
备选方案:无需修改业务代码的查找方式
如果无法调整业务代码,可通过元素层级直接定位搜索栏:
// 从导航栏中查找搜索输入框 let searchField = app.navigationBars.children(matching: .searchField).firstMatch XCTAssertTrue(searchField.exists)
内容的提问来源于stack exchange,提问作者victorydub
相关产品推荐
相关产品推荐

