使用XUIElementQuery在SwiftUI中查找表单中嵌入的DatePicker()的可访问性(标识符:)

使用XUIElementQuery在SwiftUI中查找表单中嵌入的DatePicker()的可访问性(标识符:),swiftui,xcode-ui-testing,Swiftui,Xcode Ui Testing,我有一个SwiftUI视图,其中的表单包含一个日期选择器: struct GettingUpTimeSettingView: View { @State private var viewModel = GettingUpTimeSettingViewModel() var body: some View { VStack { Form { Spacer()

我有一个SwiftUI视图,其中的表单包含一个日期选择器:

struct GettingUpTimeSettingView: View {
    @State private var viewModel = GettingUpTimeSettingViewModel()
    var body: some View {
        VStack {
            
            Form {
                Spacer()
                Text(viewModel.questionString)
                    .accessibility(identifier: "Question")
                Spacer()
                DatePicker("Alarm Time",
                                     selection: $viewModel.gettingUpTime,
                                     displayedComponents: .hourAndMinute)
                    .accessibility(identifier: "Time")
                    .animation(.easeInOut)
                Spacer()
                Text(viewModel.explanationString)
                    .accessibility(identifier: "Explanation")
            }
        }
    }
}
以及用于UI测试的XCTestCase类:

class SleepyGPIntroUITests: XCTestCase {
    
    private var app: XCUIApplication!
    
    override func setUp() {
        continueAfterFailure = false
        app = XCUIApplication()
        app.launch()
        greeting = app.staticTexts["Greeting"]
    }
    
    override func tearDown() {
        app = nil
    }
    
    func test_InitialScreen_ChangesTo_GettingUpScreen_Automatically() {
        //Given
        let questionText = "What time do you want to get up?"
        let explanationText = "This should be the same time every day, including at weekends and on days off. Our best chance of great sleep comes when we have a regular routine."
        let timeText = "7:00am"
        let question = app.staticTexts["Question"]
        let explanation = app.staticTexts["Explanation"]
        let time = app.staticTexts["Time"]
        //When
        _ = time.waitForExistence(timeout: 2)
        //Then
        XCTAssertFalse(greeting.exists)
        XCTAssertEqual(question.label, questionText, "Should show question at top of view")
        XCTAssertEqual(explanation.label, explanationText, "Should show explanation in view")
        XCTAssertEqual(time.label, timeText, "Should show the correct default time")
    }
当我运行测试时,它失败并给我以下消息:

未能获取匹配的快照:未找到与输入中谓词“标识符中的时间”匹配的元素的匹配项{( 静态文本,标识符:“问题”,标签:“你想什么时候起床?”, StaticText,标识符:'解释',标签:'这应该是每天的同一时间,包括周末和休息日。我们最好的睡眠机会是在我们有规律的时候。' )}

我不确定这是因为表单中包含了DatePicker(),还是因为我没有使用正确的XuiElementQuery来查找它

当我将日期选择器移到表单外部时,我可以找到它,但只能使用它的标签,而不是它的可访问性标识符

对于文本对象,可访问性标识符工作正常

我还可以使用

app.datePickers.firstMatch

当它在表单之外时,而不是当它包含在表单中时

我找到的答案描述了表单中包含SwiftUI对象时的一些奇怪行为,但仍然未能解决我的问题

非常感谢


tl:dr在UITesting DatePicker是否包含在SwiftUI表单中时,无法让XUIElementQuery返回DatePicker元素。

我找到了答案,适合任何感兴趣的人

首先,一条基本的建议,如果您在XCode中进行UI测试时很难找到如何访问元素,只需使用record函数并手动访问元素

这就是我所做的,它向我展示了在SwiftUI中点击DatePicker()之前,它实际上显示为一个按钮,因此在上面的示例中,为了访问它,我使用了以下代码:

let alarmTimeButton = app.tables.buttons["Time"]