运行大约500次测试后,Selenium崩溃了

时间:2014-03-06 09:56:20

标签: python selenium selenium-chromedriver

我正在尝试运行一些动态生成的测试。它们完美地工作到大约500,然后我只是得到下面的错误。有没有人见过这个?

ChromeDriver executable needs to be available in the path.  

我当时认为这可能是机器规格问题。我有一个超线程i5和8GB的RAM。看着系统监视器,我看不到内存超过6GB,CPU在任何核心上都不会达到100%。我正在运行Linux Mint。

我尝试在浏览器关闭后添加超时但似乎没有做任何事情。我注意到有很多ChromeDriver进程。他们对这个过程有一些限制吗?

任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:3)

简短回答

编辑:已确认,主要herehere中有两个错误修复;发布于2.46.0。以下内容与2.45及更早版本有关。

看来鼻子和/或硒有一个虫子。我用鼻子运行测试时可以复制这个bug;我怀疑还有其他方法可以触发它。

如果在修复bug之前需要解决方案,可以执行以下操作之一:

  • 增加允许 ...或...
  • 的最大打开文件数量
  • ...调整您的site-packages / selenium / webdriver / chrome / service.py文件

我猜你的机器上ulimit -n的输出是1024。为什么我这么想? 500 * 2接近1024(这是一个常见的设置)......继续阅读。


答案很长

这是一个微妙的错误,只有在您以某种方式运行测试时才会发生,并且环境中存在某些限制。

难以识别这是一个导致错误信息不正确的硒虫。

错误#1 ...过于宽泛的异常

Selenium通过使用过于宽泛的异常来隐藏REAL错误。如果您的测试通过了前122次运行(如我所做的那样),然后在ChromeDriver executable needs to be available in the path的每次后续测试中开始失败......那么奇怪的事情正在发生。你很可能在前120(或500)次测试的正确路径中使用了chromedriver。

因此,让我们通过告诉selenium停止假设每个引发的异常是chromedriver二进制文件不在PATH环境变量中的异常来获取真正的错误消息。

更改start

中的site-packages/selenium/webdriver/chrome/service.py方法

自:

try:
    self.process = subprocess.Popen([
      self.path,
      "--port=%d" % self.port] +
      self.service_args, env=env, stdout=PIPE, stderr=PIPE)
except:
    raise WebDriverException(
        "'" + os.path.basename(self.path) + "' executable needs to be \
        available in the path. Please look at \
        http://docs.seleniumhq.org/download/#thirdPartyDrivers \
        and read up at \
        http://code.google.com/p/selenium/wiki/ChromeDriver")

要:

try:
    self.process = subprocess.Popen([
      self.path,
      "--port=%d" % self.port] +
      self.service_args, env=env, stdout=PIPE, stderr=PIPE)
except:
    # let all exceptions reach the user, with error type and message
    # for demonstration purposes only
    raise  

现在,重新运行500次测试。您将收到更有用的错误消息,可能是:OSError: [Errno 24] Too many open files

错误#2 ...打开的文件太多

出于某种原因,stdoutstderr没有关闭。

我可以使用以下测试文件重复足够的次数来强制此错误。

# bash to duplicate: 
# for i in `seq 1 130`
# do
#    cp test_std_close.py test_std_close_$(printf %03d ${i}).py
# done

import unittest 
from selenium import webdriver

class TestStdClose(unittest.TestCase):

    def test_std_close(self):
        driver = webdriver.Chrome();
        driver.get('https://google.com');
        driver.close()

如果我将其中的130个(test_001.py,test_002.py等)放入目录并运行     nosetests std_test/test*py

我在#122上失败了,就像我的普通测试套件一样。您可能需要运行500次以复制错误。

<强>解

解决方法是提高打开文件的最大数量,或更改stop

中的site-packages/selenium/webdriver/chrome/service.py方法

自:

try:
    if self.process:
        self.process.kill()
        self.process.wait()
except OSError:
    # kill may not be available under windows environment
    pass

要:

try:
    if self.process:
        self.process.stdout.close()  # add this line
        self.process.stderr.close()  # and this one
        self.process.kill()
        self.process.wait()
except OSError:
    # kill may not be available under windows environment
    pass

这些黑客中的任何一个都将确保我的160个测试都可以在各种Mac OS配置(10.6,10.9,10.10)上执行。

我正在向硒提交错误报告和补丁;问题的根源可能在其他地方,但这两个更改中的一个修复了我的测试套件(通过鼻子运行)。

<强>结论

那么,为什么这对你来说在500后会失败?我猜你的机器上有ulimit -n个报告1024。一些数学:500 * 2(stdout,stderr)== 1000,留下你要播放的24个文件。

为什么这对我失败后会失败?因为我的小牛MacBook Pro ulimit -n报告256.有些数学:122 * 2 == 244,留下我打开的12个文件。

答案 1 :(得分:0)

正如Karna所说,这听起来像以前的测试驱动程序实例没有被清理。

您目前是否正在通过以下方式拆除浏览器:

driver.close()

任何机会?

若是,请尝试:

driver.quit()

相反,这将关闭浏览器窗口并退出驱动程序。如果你已经这样做了,那么我不确定为什么司机会留下来:(

答案 2 :(得分:0)

我找到的解决方案并不是最好的,但它确实可以很好地用于我正在使用它的目的。我所做的是将我正在使用的驱动程序从chromedriver切换到Firefox驱动程序,所有测试现在都可以使用firefox执行而没有任何问题。

答案 3 :(得分:0)

发现一些建议here说: (对于Linux)将chromedriver放在/ usr / bin下。 对于Windows,请将chromedriver放在/ Python27 / Scripts

但是,我在Win 7上的经验是将/.exe 27 /中的driver.exe文件,即chromedriver.exe,IEDriverServer.exe直接起作用。

相关问题