iOS 9 UI 测试 - 测试失败,因为目标控制不可用(尚未)

iOS 9 UI Testing - Test Fails Because Target Control Isn't Available (yet)

我正在测试 Xcode 7 的新 UI 测试功能(在 WWDC 2015 视频“UI Testing in Xcode”中介绍)。

启动时,我的应用通过更新其垂直布局约束的值将 "login panel" 设置为动画:面板从主视图下方(屏幕外)向上滑动进入视图。

面板包含两个文本字段,用户名密码

当您在键盘上点击 用户名 文本字段(标记为 "Next")的 return 键时, 密码 文本字段成为第一响应者。当您点击密码文本字段(标记为 "Go")的重新运行键时,面板为 "dismissed"(即动画后退屏幕),activity 指示器开始旋转并且身份验证开始.

我记录了执行上述操作的测试,但是当我尝试 "reproduce" 它时,它似乎失败了,因为文本字段无法立即用于输入:

Test Suite 'Selected tests' started at 2015-08-14 13:14:19.454 Test Suite 'MyAppUITests' started at 2015-08-14 13:14:19.454 Test Case '-[MyAppUITests.MyAppUITests testExample]' started.
t = 0.00s Start Test
t = 0.00s Set Up
t = 0.00s Launch com.myCompany.MyApp 2015-08-14 13:14:19.953 XCTRunner[4667:451922] Continuing to run tests in the background with task ID 1
t = 2.64s Waiting for accessibility to load
t = 6.20s Wait for app to idle
t = 6.49s Tap "User ID" TextField
t = 6.49s Wait for app to idle
t = 6.57s Find the "User ID" TextField
t = 6.57s Snapshot accessibility hierarchy for com.myCompany.MyApp
t = 6.60s Find: Descendants matching type TextField
t = 6.60s Find: Elements matching predicate '"User ID" IN identifiers'
t = 6.60s Wait for app to idle
t = 6.67s Synthesize event
t = 6.74s Scroll element to visible
t = 6.78s Assertion Failure: UI Testing Failure - Failed to scroll to visible (by AX action) TextField 0x7fc90251a130: traits: 146029150208, {{107.0, 807.0}, {200.0, 30.0}}, placeholderValue: 'User ID', value: fffffaaaa, error: Error -25204 performing AXAction 2003 :0: error: -[MyAppUITests.MyAppUITests testExample] : UI Testing Failure - Failed to scroll to visible (by AX action) TextField 0x7fc90251a130: traits: 146029150208, {{107.0, 807.0}, {200.0, 30.0}}, placeholderValue: 'User ID', value: fffffaaaa, error: Error -25204 performing AXAction 2003
t = 6.78s Tear Down Test Case '-[MyAppUITests.MyAppUITests testExample]' failed (6.783 seconds).
Test Suite 'MyAppUITests' failed at 2015-08-14 13:14:26.238.
Executed 1 test, with 1 failure (0 unexpected) in 6.783 (6.784) seconds

(强调我的。项目名称和包 ID 更改为假值)

如何处理这样的 UI? (即,测试代码必须等待某个动画完成,目标控件才能运行)

我不记得提到这些 'timing' 问题的视频。

我建议 against 勾选 运行 循环,而是使用内置的 XCTest 异步 API。例如:

let app = XCUIApplication()
app.launch()

let textField = app.textField["user name"]
let existsPredicate = NSPredicate(format: "exists == 1")

expectationForPredicate(existsPredicate, evaluatedWithObject: textField, handler: nil)
waitForExpectationsWithTimeout(5, handler: nil)

textField.tap()
textField.type("joemasilotti")

这将等到具有辅助功能的文本字段 label/identifier "username" 实际存在于屏幕上。然后它会点击文本字段,使其处于活动状态,然后输入我的用户名。如果在这变为真之前过了五秒,测试将失败。

我也在 how to use UI Testing on my blog and put together a UI Testing Cheat Sheet 上写了一个 post 用于类似的场景。