【问题标题】:How can I write UI tests for a SwiftUI InputField如何为 SwiftUI InputField 编写 UI 测试
【发布时间】:2021-05-20 11:07:23
【问题描述】:

我有这个 SwiftUI 视图(将删除不相关的部分)

struct LoginView: View {
    
    var body: some View {
        VStack {
            Spacer()
            InputField(title: "Email", text: $email)
            InputField(title: "Password", text: $password, showingSecureField: true)
            InputField(title: "Store", text: $userStore)
            CallToActionButton(
                title: newUser ? "Register User" : "Log In",
                action: userAction
            )
            Button(action: { newUser.toggle() }) {
                HStack {
                    CheckBox(title: "Create Account", isChecked: $newUser)
                    Spacer()
                }
            }
            Spacer()
        }
    }

我可以使用以下代码为该按钮编写 UI 测试:

    func testClickLoginButton() throws {
        let app = XCUIApplication()
        app.launch()
                  
        let startButton = app.buttons["Log In"]
        XCTAssertTrue(startButton.waitForExistence(timeout: 1))
        XCTAssertTrue(startButton.isEnabled)
        startButton.tap()
    }

而且它有效,因为屏幕上有一个带有该标题的按钮。

但是我想自动在这些 InputTexts 中放入一些文本并测试它们,但找不到它们,因为它们既不是 UITextField 也不是 UITextView。我怎样才能做到这一点?谢谢!

    func testAddEmail() throws {
        let app = XCUIApplication()
        app.launch()

        // fails as can't find any text field containing "Email"
                           
        let emailText = app.textFields["Email"]
        XCTAssertTrue(emailText.waitForExistence(timeout: 1))
        emailText.typeText("testemail@realm.com")
        XCTAssertEqual(emailText.value as! String, "testemail@realm.com")
    }

【问题讨论】:

    标签: swift swiftui xcode-ui-testing


    【解决方案1】:

    如何添加:

     InputField(title: "Email", text: $email)
            .accessibility(identifier: "email_input")
    

    对于您想从 UI 测试中测试的任何其他元素也是如此?

    【讨论】:

      【解决方案2】:

      我不是专家,我见过在 SwiftUI 中进行 UITests 的不同方法。快照等可能有更好的方法,但我很快重新创建了您的示例,并添加了一个可访问性标识符:

      struct InputField: View {
          var title: String
          @Binding var email: String
      
          var body: some View {
              VStack(alignment: .leading) {
                  Text("Enter your email ")
                  TextField(title, text: $email)
                      .accessibility(identifier: "Email")
      
              }
              .padding()
          }
      }
      
      struct ContentView: View {
          @State private var email: String = ""
      
          var body: some View {
                  InputField(title: "Email: ", email: $email)
          }
      }
      

      此外,有时可能需要在输入电子邮件或文本之前添加一个点击。因此,它给了我一个错误。
      UItest 看起来像这样并且正在通过:)

          func testAddEmail() throws {
              let app = XCUIApplication()
              app.launch()
      
              let emailText = app.textFields["Email"]
              XCTAssertTrue(emailText.waitForExistence(timeout: 1))
              emailText.tap() 
              emailText.typeText("testemail@realm.com")
      
              XCTAssertEqual(emailText.value as! String, "testemail@realm.com")
          }
      

      我学到的一个很酷的技巧是这样设置断点:

      并在调试器的提示符处输入以下内容:

      (lldb) po XCUIApplication().textFields
      

      所以你得到了这个列表,你看看是否缺少标识符。按钮和静态文本等也是如此。

      【讨论】:

        猜你喜欢
        • 2022-06-12
        • 2021-02-26
        • 1970-01-01
        • 1970-01-01
        • 2021-12-18
        • 2020-12-22
        • 2021-02-03
        • 2015-09-11
        • 2015-02-16
        相关资源
        最近更新 更多