UI 当 运行 由 Xcode 机器人将文本键入文本视图时,测试失败

UI test fails when it types text into a text view when run by an Xcode bot

我有以下 XCTest UI 测试将文本键入文本视图。

let textView = app.textViews.elementBoundByIndex(0)
textView.tap()
textView.typeText("Hello world")

当 运行 作为 Xcode 机器人时,它显示 typeText 调用的以下错误。

Assertion: UI Testing Failure - failed: Timed out waiting for key event to complete

有趣的是,当我从同一台计算机上的 Xcode 手动 运行 它时,测试通过了。在升级到 Xcode 7.1 / iOS 9.1 之前,此测试也在 Xcode bot 中通过。问题的根源是什么?

这是一个带有 UI 测试的独立演示: https://github.com/exchangegroup/UITestTextViewDemo

iOS 9.1 模拟器,OS X 10.11.1 (15B42),Xcode 7.1 (7B91b),OS X 服务器 5.0.15 (15S4033)

已报告给 Apple。

我找到了解决方案,希望对您也有帮助。

在我的 setUp()tearDown() 中(我知道这似乎是多余的)我放了 XCUIApplication().terminate()。这是为了确保应用程序在 运行 下一次测试之前终止,它似乎正在完成这项工作。

override func setUp() {
    XCUIApplication().terminate()
    super.setUp()
    continueAfterFailure = false
    XCUIApplication().launch()
}
override func tearDown() {
    super.tearDown()
    XCUIApplication().terminate()
}

我向 Apple 提交了一个错误,但目前这让我解决了你看到的错误。希望对您有所帮助!

我找到了另一个解决方案,因为 Konnor 提出的那个对我不起作用:我在 Xcode Bot 上使用 UITest 时遇到很多问题,常见的症状是在模拟器上进行测试比在本地机器上花费更多的时间,所以我认为 _xcsbuildd 用户习惯于 运行 测试在某种程度上变慢了。

我的解决方案很简单:只需将 _xcsbuildd 用户提升为 "normal" 用户即可。这还有另一个好处:如果您愿意,您可以使用该用户登录并在集成期间在模拟器中查看测试 运行,因此更容易调试!

我是这样做的:

sudo dscl . -create /Users/_xcsbuildd UserShell /bin/bash
sudo dscl . -create /Users/_xcsbuildd FirstName Xcode
sudo dscl . -create /Users/_xcsbuildd LastName Server
sudo dscl . -create /Users/_xcsbuildd FullName "Xcode Server"
sudo dscl . -create /Users/_xcsbuildd PrimaryGroupID 20

然后更改密码:

sudo dscl . -passwd /Users/_xcsbuildd

我无法让用户显示在快速登录 window 中,无论如何你应该看到一个 "other user",你可以在其中插入用户名“_xcsbuildd”和你选择的密码

我认为潜在的问题是 "Connect Hardware Keyboard" 默认打开。即使您为主要用户关闭它,_xcsbuildd 用户仍然使用默认值。我能够通过使用以下脚本向方案添加预测试操作来解决问题:

if [ `defaults read com.apple.iphonesimulator ConnectHardwareKeyboard` -eq 1 ]
 then
  defaults write com.apple.iphonesimulator ConnectHardwareKeyboard -bool false
  killall "Simulator"
fi

我也运行关注这个问题。我已经编写了一个 UI 测试来使用 Snapshot (fastlane) 捕获屏幕截图,它在 iPad Air & Pro 模拟器上运行良好。但是,在 iPad Retina 或 iPad 2 模拟器上,我从命令行 运行 或直接从 Xcode.

收到此错误消息

我的解决方案是在 typeText() 语句之间添加一些 sleep() 函数,错误消失了。

Edit:这仅通过命令行从 Xcode 手动修复 运行,它仍然会导致测试失败。我还注意到它适用于 64 位设备的所有模拟器,但不适用于早期设备。

编辑 2:我找到了解决此问题的方法,方法是使用 iOS 9.0 模拟器而不是 iOS 9.3,如本文所述答案:。在 Xcode.

的新版本中得到修复之前,这似乎是一个很好的解决方法

除了连接硬件键盘,none 这些东西对我来说真的很管用。起作用的是 关闭 Mac 的屏幕保护程序并在系统设置中显示休眠 。我怀疑当 Mac 被锁定或没有可绘制的监视器时,模拟器表现异常。

关闭这两个设置后,我仍然会遇到一些随机的 UI 测试失败。连接硬件监视器或屏幕共享以便在屏幕上某处绘制模拟器似乎可以解决这些问题。

我在 ios 9.3 版本上使用 xcode 8.2.1 和 运行 测试。一个简单的 hack 是在点击文本框之后和输入之前添加 2-5 秒的睡眠。不过,这不是永久性的解决方案。

另一个可靠的解决方案

在 运行 测试之前取消选择设置中的所有键盘首选项。

"KeyboardAllowPaddle": false,
"KeyboardAssistant": false,
"KeyboardAutocapitalization": false,
"KeyboardAutocorrection": false,
"KeyboardCapsLock": false,
"KeyboardCheckSpelling": false,
"KeyboardPeriodShortcut": false,
"KeyboardPrediction": false,
"KeyboardShowPredictionBar": false