Xcode UI测试找到多个按钮

时间:2017-05-30 01:34:22

标签: ios swift xcode xcode-ui-testing

我遇到问题,我的UI测试显示使用以下代码时找到多个按钮。

app.buttons["Upgrade"].tap()

所以我重新进行单元测试并在运行该行之前设置断点并点击记录按钮并单击按钮并生成以下代码。

app.children(matching: .window).element(boundBy: 0).children(matching: .other).element(boundBy: 1).buttons["Upgrade"].tap()

当然,在测试的顶部,我有let app = XCUIApplication()

知道为什么会这样吗?

有时在调试器中运行p UIApplication.shared.windows时,它在数组中有2个值。我不知道为什么我从来没有多个窗户。我与Windows进行的唯一互动有时会将UIApplication.shared.keyWindow?.rootViewController设置为不同的视图控制器,以及didFinishLaunchingWithOptions中的以下代码。

// Get view controllers ready
self.window = UIWindow(frame: UIScreen.main.bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let mainViewController: ViewController = mainStoryboard.instantiateViewController(withIdentifier: "FirstView") as! ViewController
// Show view controller
self.window?.rootViewController = mainViewController
self.window?.makeKeyAndVisible()

这是在if语句中,在else语句中我有几乎相同的代码,而不是FirstViewSecondView

3 个答案:

答案 0 :(得分:4)

出现此消息是因为屏幕上有多个按钮accessibilityIdentifieraccessibilityLabel value,“升级”,因此可以找不到哪一个。

使用录制版本时它起作用的原因是因为录制工具已确定需要缩小搜索范围以在索引.other处的1类型的元素内搜索,为了确定与之交互的“升级”按钮。

这不是您的窗口的问题,而是您的按钮标识符的唯一性,以及您在测试中如何处理它们。

如果该按钮仅在相关应用的页面上使用过一次,则最好在accessibilityIdentifier上设置唯一的UIButton。它的值应该在您应用的该页面中是唯一的,因此请确保您在其他任何地方都没有使用相同的字符串。然后您可以明确地访问该按钮:

// app code
let upgradeButton: UIButton!
upgradeButton.accessibilityIdentifier = "upgradeButton"

// test code
let app = XCUIApplication()
let upgradeButton = app.buttons["upgradeButton"]
upgradeButton.tap()

在同一时间屏幕上有多个同一升级按钮实例的情况下(例如,按钮是屏幕上重复图案的一部分,就像有很多待售产品一样),没关系对于他们每个人都有相同的accessibilityIdentifier,但你应该改变你在测试中访问元素的方式,使用element(boundBy:)来访问指定索引处的项目:

// app code
let upgradeButton: UIButton!
upgradeButton.accessibilityIdentifier = "upgradeButton"

// test code
let app = XCUIApplication()
let upgradeButton = app.buttons["upgradeButton"].element(boundBy: 1) // second upgrade button
upgradeButton.tap()

在这种情况下,您还可以采用找到正确容器视图的方法,并在其中搜索升级按钮。

// test code
let app = XCUIApplication()
let upgradeButtonContainer = app.descendants(matching: .any).containing(.button, identifier: "upgradeButton").element(boundBy: 1) // second upgrade button-containing element
let upgradeButton = upgradeButtonContainer.buttons["upgradeButton"]
upgradeButton.tap()

答案 1 :(得分:0)

自从更新到XCode 8.3后,我看到类似的问题,XCUIElementQuery在应该只有一个时返回多个结果。此版本中可能存在错误。

https://forums.developer.apple.com/thread/75546 描述了这个错误,雷达在这里: https://openradar.appspot.com/31498932

我尝试强制查询以将所需对象作为XCUIElementQuery返回,然后使用element(boundBy:)并尝试对我发挥作用,尝试了已发布的解决方法。

它打乱了UI测试的不稳定性。

答案 2 :(得分:0)

我遇到了同样的问题并尝试了多种方法来摆脱它。最终我发现当我将Xcode更新到8.3.3并将模拟器操作系统更新到iOS 10.3时,问题就开始发生了。 将我的模拟器操作系统切换回iOS 10.2,它完美运行。