如何为 SwiftUI InputField 编写 UI 测试
How can I write UI tests for a SwiftUI InputField
我有这个 SwiftUI 视图(将删除 non-relevant 部分)
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()
}
它起作用了,因为屏幕上有一个带有该标题的按钮。
但后来我想自动在这些 InputText 中放入一些文本并对其进行测试,但找不到它们,因为它们既不是 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")
}
如何添加:
InputField(title: "Email", text: $email)
.accessibility(identifier: "email_input")
对于您想从 UI 测试中测试的任何其他元素也是如此吗?
我不是专家,也见过在 SwiftUI 中执行 UITest 的不同方法。快照等可能有更好的方法,但为了好玩我很快重新创建了您的示例并添加了可访问性标识符:
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
这样您就得到了列表,您可以查看是否缺少标识符。按钮和静态文本等也是如此
我有这个 SwiftUI 视图(将删除 non-relevant 部分)
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()
}
它起作用了,因为屏幕上有一个带有该标题的按钮。
但后来我想自动在这些 InputText 中放入一些文本并对其进行测试,但找不到它们,因为它们既不是 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")
}
如何添加:
InputField(title: "Email", text: $email)
.accessibility(identifier: "email_input")
对于您想从 UI 测试中测试的任何其他元素也是如此吗?
我不是专家,也见过在 SwiftUI 中执行 UITest 的不同方法。快照等可能有更好的方法,但为了好玩我很快重新创建了您的示例并添加了可访问性标识符:
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
这样您就得到了列表,您可以查看是否缺少标识符。按钮和静态文本等也是如此