SwiftUI/XCUIApplication如何添加标识符测试形状元素存在性
解决方案
直接给加载指示器的外层根容器(也就是包裹三个圆点的HStack)添加accessibilityIdentifier修饰符即可,这个修饰符是SwiftUI专门为UI测试设计的定位标识,不会影响应用的正常展示和业务逻辑。
为了避免XCTest匹配到HStack内部的三个Circle子元素、出现「多个元素匹配同一个标识符」的报错,建议同时把HStack设置为独立的可访问元素,直接忽略子元素的可访问属性,不需要给每个圆点单独加标识。
修改后的完整代码如下:
var body: some View { HStack { Circle() .fill(dotColor) .opacity(shouldAnimate ? 1 : 0.1) .frame(width: dotSize, height: dotSize) .scaleEffect(shouldAnimate ? 1.1 : 0.9) .animation(easyDoesIt, value: shouldAnimate) Circle() .fill(dotColor) .opacity(shouldAnimate ? 1 : 0.1) .frame(width: dotSize, height: dotSize) .scaleEffect(shouldAnimate ? 1.1 : 0.9) .animation(easyDoesIt.delay(0.2), value: shouldAnimate) Circle() .fill(dotColor) .opacity(shouldAnimate ? 1 : 0.1) .frame(width: dotSize, height: dotSize) .scaleEffect(shouldAnimate ? 1.1 : 0.9) .animation(easyDoesIt.delay(0.4), value: shouldAnimate) } // 以下为UI测试新增的配置 .accessibilityElement(children: .ignore) .accessibilityIdentifier("loading_indicator") .onAppear { self.shouldAnimate = true } }
测试用例写法
在UI测试 target 中,你可以直接通过自定义的标识符抓取元素,判断加载指示器的展示状态:
func testLoadingIndicatorShow() { let app = XCUIApplication() app.launch() // 等待指示器出现,最多等2秒 let loadingIndicator = app.otherElements["loading_indicator"] XCTAssertTrue(loadingIndicator.waitForExistence(timeout: 2)) // 如果需要判断指示器是否覆盖了页面交互,可以用isHittable判断 // XCTAssertTrue(loadingIndicator.isHittable) }
常见坑点
- 不要用
accessibilityLabel作为测试定位标识,这个属性是给VoiceOver等辅助功能读的文案,会跟随系统语言变化,作为测试标识会导致多语言环境下用例失败 - 如果加载指示器是放在弹窗、导航栏、列表cell等特殊容器内,可以缩小查询范围提升匹配效率,比如
app.alerts.firstMatch.otherElements["loading_indicator"] - 加了
.accessibilityElement(children: .ignore)不会影响动画效果,普通用户完全感知不到,只会让辅助功能和UI测试把整个HStack当成单个元素处理
内容的提问来源于stack exchange,提问作者Surplus Yogurt
相关产品推荐
相关产品推荐

