一尘不染

selenium运行约500次测试后崩溃

selenium

我正在尝试运行一些动态生成的测试。它们可以完美地工作到大约500,然后我得到下面的错误。谁看过这个吗?

ChromeDriver executable needs to be available in the path.

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

我已经尝试在浏览器关闭后添加超时,但是似乎没有任何作用。我注意到,ChromeDriver进程有很多负载。他们对此过程有某种限制吗?

任何帮助,将不胜感激。


阅读 604

收藏
2020-06-26

共1个答案

一尘不染

简短答案

编辑:确认,此处此处的
master中有两个错误;在2.46.0中发布。以下与2.45及更早版本有关。

鼻子和/或硒中似乎有虫子。使用鼻子进行测试时,我可以复制此错误;我怀疑还有其他触发方式。

如果您需要在漏洞修复之前找到解决方案,则可以执行以下任一操作:

  • 增加允许的最大打开文件数 …或…
  • …调整您的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……这很奇怪。您显然在第一个122(或500)个测试的正确路径中安装了chromedriver。

因此,让我们停止硒,假设每个引发的异常都是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个文件可玩。

为什么在〜122之后对我来说失败了?因为在我的Mavericks上MacBook Pro ulimit -n报告为256。一些数学运算:122 * 2
== 244,剩下12个可打开的文件供您使用。

2020-06-26