【问题标题】:iOS 9 UI Testing - Test Fails Because Target Control Isn't Available (yet)iOS 9 UI 测试 - 测试失败,因为目标控制不可用(还)
【发布时间】:2015-11-07 06:04:51
【问题描述】:

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

在启动时,我的应用程序通过更新其垂直布局约束的值将“登录面板”动画化到视图中:面板从主视图下方(屏幕外)向上滑动进入视图。

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

当您在用户名文本字段(标记为“下一步”)的键盘上点击返回键时,密码文本字段将成为第一响应者。当您点击密码文本字段(标记为“开始”)的重新运行键时,面板将“关闭”(即动画后退屏幕),活动指示器开始旋转并开始身份验证。

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

测试套件“选定测试”开始于 2015-08-14 13:14:19.454 测试 套件“MyAppUITests”开始于 2015-08-14 13:14:19.454 测试用例 '-[MyAppUITests.MyAppUITests testExample]' 已启动。
t = 0.00s 开始测试
t = 0.00s 设置
t = 0.00s Launch com.myCompany.MyApp 2015-08-14 13:14:19.953 XCTRunner[4667:451922] 继续在 任务 ID 为 1 的背景
t = 2.64s 等待可访问性加载
t = 6.20s 等待应用空闲
t = 6.49s 点击“用户 ID”文本字段
t = 6.49s 等待应用空闲
t = 6.57s 查找“用户 ID”文本字段
t = 6.57s com.myCompany.MyApp 的快照可访问性层次结构
t = 6.60s 查找:后代匹配类型 TextField
t = 6.60s 查找:匹配谓词“用户 ID”IN 标识符的元素
t = 6.60s 等待应用空闲
t = 6.67s 合成事件
t = 6.74s 将元素滚动到可见
t = 6.78s 断言失败:UI 测试失败 - 无法滚动到可见(通过 AX 操作)TextField 0x7fc90251a130: 特征:146029150208, {{107.0, 807.0}, {200.0, 30.0}}, placeholderValue:“用户 ID”,值:fffffaaaa,错误:错误 -25204 执行 AXAction 2003 :0: 错误: -[MyAppUITests.MyAppUITests testExample]:UI 测试失败 - 无法滚动到可见(通过 AX 操作)TextField 0x7fc90251a130: 特征: 146029150208, {{107.0, 807.0}, {200.0, 30.0}}, placeholderValue: '用户 ID',值:fffffaaaa,错误:错误 -25204 执行 AXAction 2003
t = 6.78s 拆除测试用例 '-[MyAppUITests.MyAppUITests testExample]' 失败(6.783 秒)。
测试套件“MyAppUITests”在 2015-08-14 13:14:26.238 失败。
执行 1 次测试,在 6.783 (6.784) 中有 1 次失败(0 次意外) 秒

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

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

我不记得视频中提到了这些“时间”问题。

【问题讨论】:

    标签: ios ios9 xcode-ui-testing


    【解决方案1】:

    我建议反对勾选运行循环,而是使用内置的 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")
    

    这将等到具有可访问性标签/标识符“用户名”的文本字段实际存在于屏幕上。然后它将点击文本字段,使其处于活动状态,然后输入我的用户名。如果在这成为 true 之前经过 5 秒,则测试将失败。

    我还在我的博客上写了一篇关于how to use UI Testing 的帖子,并为这样的场景整理了一个UI Testing Cheat Sheet

    【讨论】:

    • 谢谢...我想我只是在评论中引用了你的博客。
    • 强烈同意这种做法。勾选运行循环和轮询会产生比expectationForPredicate / waitForExpectationsWithTimeout 更不可靠的测试
    • 最近在 swift 中的更改将名称更改为 expectation(for: existsPredicate, evaluatedWith: textField, handler: nil)waitForExpectations(timeout: 5, handler: nil)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-29
    • 2013-12-01
    相关资源
    最近更新 更多