运行 使用 Capybara 和 headless Chrome 进行功能测试时出现 EOFError
EOFError when running feature tests with Capybara and headless Chrome
编辑:事实证明,这整个问题是由于我们的 WEBrick 项目中隐藏且命名不当的猴子补丁造成的,Capybara 将其用作其默认 Web 服务器。 Whosebug 不允许我删除问题,所以在进一步阅读时要小心。
我们正在尝试将 Ruby 版本从 2.2.7 升级到 2.4.3。该应用程序本身 运行 正常,但我们所有通过 Capybara 和 headless Chrome(使用 Chrome 驱动程序)运行 的功能测试突然失败。
这是我们看到的确切错误的示例:
Failures:
1) New UI - Settings Page - API with an unpermitted tier clicking on the "Request API Key" button shows a feature popup
Got 0 failures and 2 other errors:
1.1) Failure/Error: Unable to find matching line from backtrace
EOFError:
end of file reached
1.2) Failure/Error: Unable to find matching line from backtrace
EOFError:
end of file reached
下面是我们为无头配置 Selenium 驱动程序的方式 Chrome:
CHROME_BINARY = ENV.fetch('CHROME_BINARY', '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome')
Capybara.register_driver :headless_chrome do |app|
Capybara::Selenium::Driver.new(
app,
browser: :chrome,
desired_capabilities: Selenium::WebDriver::Remote::Capabilities.chrome(
'chromeOptions' => {
'binary' => CHROME_BINARY,
'args' => %w(no-sandbox disable-gpu window-size=1440,900 headless)
}
)
)
end
Ruby版本:2.4.3
Chrome驱动版本:2.35.528157
水豚版本:2.18.0
RSpec版本:3.7.0
硒网络驱动程序:3.9.0
Chrome: 64.0.3282.167
我所做的所有其他研究表明,将 Chrome 驱动程序更新到最新版本将解决此问题,但我们已经在使用最新版本 (2.3.5)。
我一直没能找到一种方法来获取上述错误的更多回溯信息。该规范甚至没有达到从数据库加载任何内容的程度,它只是立即失败。
另一件需要注意的事情:我们的 CI 服务器和本地开发机器上都发生了同样的行为。我们将 CircleCI 与 Dockerized Linux 容器一起使用,并为我们的开发机器使用 MacOS Sierra/High Sierra。
我们没有使用 chromedriver-helper 或任何其他自动安装 chromedriver 的 gem。 chromedriver 的安装是通过 brew install chromedriver
或从 chromedriver 网站下载最新的 chromedriver 并放置在我们的 $PATH
.
中完成的
更新:这个问题的根源是 WEBrick 的猴子补丁。它的名字不好,位于一个不寻常的位置,作者不再在团队中。一个很好的提醒,应该不惜一切代价避免使用 monkeypatches。
原回答:
我一直在与 Jordan (OP) 合作解决这个问题。虽然我们还没有找到根本原因,但我们已经找到了没有回溯的 EOFError 的来源。
下面的代码可以在Ruby的标准库中找到:Net::BufferedIO#rbuf_fill
https://github.com/ruby/ruby/blob/v2_4_3/lib/net/protocol.rb#L185
# callers do not care about backtrace, so avoid allocating for it
raise EOFError, 'end of file reached', []
我的猜测是这段代码的作者希望这个错误在某个时候会被挽救。可能存在允许错误到达我们的错误,并且没有回溯。
正如我所说,我们从未找到根本原因。然而,我们确实将范围缩小到我们能够找到可接受的解决方法的程度。该问题似乎与 Webrick 有关,Webrick 是水豚在未指定的情况下默认使用的服务器
- 当一个新的水豚会话被初始化时,Capybara::Server 的一个实例被“启动”,这在我们的例子中是 webrick:https://github.com/teamcapybara/capybara/blob/2.18_stable/lib/capybara/session.rb#L88
- 启动过程的一部分是检查服务器是否“响应”:https://github.com/teamcapybara/capybara/blob/2.18_stable/lib/capybara/server.rb#L105
- 响应方法向服务器 (127.0.0.1) 发出
get
请求:https://github.com/teamcapybara/capybara/blob/2.18_stable/lib/capybara/server.rb#L82
- 此时剩下的在 ruby 的 http 库中。最终它在这里因 EOFError 失败:https://github.com/ruby/ruby/blob/v2_4_3/lib/net/protocol.rb#L185
我假设 Webrick 反应异常,或者根本没有反应。如果有人对此有更深入的了解,我很乐意学习
在我们的案例中,解决方法很简单。该应用程序已经在其他环境中使用 puma,因此我们决定尝试将 puma 与 capybara 结合使用,看看它是否能让我们解决这个问题:
Capybara.server = :puma
因为Capybara的机架服务器不再使用,我们不再受到影响。
如果其他人遇到同样的问题或对根本原因有想法,请分享!
编辑 1:
在逐步执行代码时,我在到达 rbuf_fill
时抓取了 caller
的结果。对于那些感兴趣的人,我已经上传到这里:https://gist.github.com/benjaminwood/c7c0d39fcfb2efd8a9085874cac07c36
编辑 2:
更新了有关 Webrick 作为水豚默认服务器的信息。感谢@Thomas Walpole 澄清这一点。
编辑 3:
添加有关分辨率的注释(这是一个 monkeypatch)。
编辑:事实证明,这整个问题是由于我们的 WEBrick 项目中隐藏且命名不当的猴子补丁造成的,Capybara 将其用作其默认 Web 服务器。 Whosebug 不允许我删除问题,所以在进一步阅读时要小心。
我们正在尝试将 Ruby 版本从 2.2.7 升级到 2.4.3。该应用程序本身 运行 正常,但我们所有通过 Capybara 和 headless Chrome(使用 Chrome 驱动程序)运行 的功能测试突然失败。
这是我们看到的确切错误的示例:
Failures:
1) New UI - Settings Page - API with an unpermitted tier clicking on the "Request API Key" button shows a feature popup
Got 0 failures and 2 other errors:
1.1) Failure/Error: Unable to find matching line from backtrace
EOFError:
end of file reached
1.2) Failure/Error: Unable to find matching line from backtrace
EOFError:
end of file reached
下面是我们为无头配置 Selenium 驱动程序的方式 Chrome:
CHROME_BINARY = ENV.fetch('CHROME_BINARY', '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome')
Capybara.register_driver :headless_chrome do |app|
Capybara::Selenium::Driver.new(
app,
browser: :chrome,
desired_capabilities: Selenium::WebDriver::Remote::Capabilities.chrome(
'chromeOptions' => {
'binary' => CHROME_BINARY,
'args' => %w(no-sandbox disable-gpu window-size=1440,900 headless)
}
)
)
end
Ruby版本:2.4.3
Chrome驱动版本:2.35.528157
水豚版本:2.18.0
RSpec版本:3.7.0
硒网络驱动程序:3.9.0
Chrome: 64.0.3282.167
我所做的所有其他研究表明,将 Chrome 驱动程序更新到最新版本将解决此问题,但我们已经在使用最新版本 (2.3.5)。
我一直没能找到一种方法来获取上述错误的更多回溯信息。该规范甚至没有达到从数据库加载任何内容的程度,它只是立即失败。
另一件需要注意的事情:我们的 CI 服务器和本地开发机器上都发生了同样的行为。我们将 CircleCI 与 Dockerized Linux 容器一起使用,并为我们的开发机器使用 MacOS Sierra/High Sierra。
我们没有使用 chromedriver-helper 或任何其他自动安装 chromedriver 的 gem。 chromedriver 的安装是通过 brew install chromedriver
或从 chromedriver 网站下载最新的 chromedriver 并放置在我们的 $PATH
.
更新:这个问题的根源是 WEBrick 的猴子补丁。它的名字不好,位于一个不寻常的位置,作者不再在团队中。一个很好的提醒,应该不惜一切代价避免使用 monkeypatches。
原回答:
我一直在与 Jordan (OP) 合作解决这个问题。虽然我们还没有找到根本原因,但我们已经找到了没有回溯的 EOFError 的来源。
下面的代码可以在Ruby的标准库中找到:Net::BufferedIO#rbuf_fill
https://github.com/ruby/ruby/blob/v2_4_3/lib/net/protocol.rb#L185
# callers do not care about backtrace, so avoid allocating for it
raise EOFError, 'end of file reached', []
我的猜测是这段代码的作者希望这个错误在某个时候会被挽救。可能存在允许错误到达我们的错误,并且没有回溯。
正如我所说,我们从未找到根本原因。然而,我们确实将范围缩小到我们能够找到可接受的解决方法的程度。该问题似乎与 Webrick 有关,Webrick 是水豚在未指定的情况下默认使用的服务器
- 当一个新的水豚会话被初始化时,Capybara::Server 的一个实例被“启动”,这在我们的例子中是 webrick:https://github.com/teamcapybara/capybara/blob/2.18_stable/lib/capybara/session.rb#L88
- 启动过程的一部分是检查服务器是否“响应”:https://github.com/teamcapybara/capybara/blob/2.18_stable/lib/capybara/server.rb#L105
- 响应方法向服务器 (127.0.0.1) 发出
get
请求:https://github.com/teamcapybara/capybara/blob/2.18_stable/lib/capybara/server.rb#L82 - 此时剩下的在 ruby 的 http 库中。最终它在这里因 EOFError 失败:https://github.com/ruby/ruby/blob/v2_4_3/lib/net/protocol.rb#L185
我假设 Webrick 反应异常,或者根本没有反应。如果有人对此有更深入的了解,我很乐意学习
在我们的案例中,解决方法很简单。该应用程序已经在其他环境中使用 puma,因此我们决定尝试将 puma 与 capybara 结合使用,看看它是否能让我们解决这个问题:
Capybara.server = :puma
因为Capybara的机架服务器不再使用,我们不再受到影响。
如果其他人遇到同样的问题或对根本原因有想法,请分享!
编辑 1:
在逐步执行代码时,我在到达 rbuf_fill
时抓取了 caller
的结果。对于那些感兴趣的人,我已经上传到这里:https://gist.github.com/benjaminwood/c7c0d39fcfb2efd8a9085874cac07c36
编辑 2:
更新了有关 Webrick 作为水豚默认服务器的信息。感谢@Thomas Walpole 澄清这一点。
编辑 3:
添加有关分辨率的注释(这是一个 monkeypatch)。