使用selenium webdriver进行tcp / ip端口耗尽

时间:2012-10-17 14:23:55

标签: python selenium webdriver urllib2 tcp-ip

我正在使用selenium webdriver(用Python编写)进行一系列测试。正在测试的页面包含一个表单,该表单根据在其中一个选择框中选择的值来更改其显示的字段。此选择框有大约250个选项。我有一个测试(通过鼻子运行,虽然这可能是不相关的)迭代选择框中的所有选项,验证表单是否为每个选定的选项显示了正确的字段。

问题在于,对于每个选项,它都通过selenium调用:

  • 点击选项以选择
  • 7个字段的find_element和is_displayed
  • 选择框中项目的find_elements
  • get_attribute和选择框中每个选项的文字

因此,对于运行测试的webdriver服务器(大约)250 *(7 * 2 + 1 + 2 * 250)或128,750个不同的请求,所有这些请求都在大约10或15分钟内完成。在某些情况下,这会导致运行测试的计算机上的客户端端口耗尽。这一切都是通过一个测试框架来完成的,这个测试框架抽象出了解析选择框的方式,创建新页面对象的时间以及其他一些事情,因此测试代码中的优化或者意味着将所有内容全部破坏或丢弃这个测试的框架并手动完成所有操作(为了我们的测试代码的可维护性,这是一个坏主意)。

我对解决方案的一些想法是:

  • 尝试以某种方式池化或重用与webdriver服务器的连接
  • 以某种方式在运行时调整urllib2httplib的配置,以便通过selenium超时打开连接或者更快地杀死
  • 系统无关(或至少可实现所有具有OS交换机或其他系统的系统)机制,用于主动跟踪和关闭由selenium打开的端口

正如我上面提到的,我无法调整页面的解析或处理方式,但我确实可以控制子类化/调整WebDriverRemoteConnection。有没有人对如何处理上述任何想法或任何我没想过的想法有任何建议?

3 个答案:

答案 0 :(得分:2)

在少量塑料炸药解决了忘记房门钥匙的问题时,我实施了一个解决方案。我创建了一个类,它跟踪资源列表及其添加时间,在达到限制时阻塞,并在时间戳超过超时值时删除条目。然后我创建了这个类设置的实例,限制为32768个资源,超时为240秒,并且每次调用webdriver.execute()或其他一些操作时,我的测试框架都会向列表添加一个条目(db查询) ,执行REST调用)。它不是特别优雅,而且非常随意,但至少到目前为止它似乎是让我的测试不会触发端口耗尽,而不会明显减慢之前没有导致端口耗尽的测试。

答案 1 :(得分:0)

有同样的问题。我将发布我的解决方案以供将来参考(虽然它很可能不如你的,但它是基本的,我不能浪费我的时间在这上面。)

我不知道Selenium为每个javascript调用创建新套接字的原因。听起来像是架构问题。

这使得任何类型的爬行都非常困难,并且也会使冗长的集成测试失败。

一些可能的修复:

1)开始使用linux - 我在某个地方看到一个家伙只在Windows系统上有这个端口耗尽。显然,不是那么好的解决方案。

2)关注msdn文章以避免tcp / ip端口耗尽,这样做对我来说。 https://msdn.microsoft.com/en-us/library/aa560610(v=bts.20).aspx

即,您应该增加MaxUserPort,然后减少TcpTimedWait。这些可以在没有管理员访问权限的情况下修改,也许您的测试可能包括对这些设置的注册表检查。

3)创建新类,让旧的tcp连接死掉:

public class LoanCrawlerSpeedController : ILoanCrawlerSpeedController
{
    private DateTime _lastCheckpointTime = DateTime.Now;

    public void Checkpoint()
    {
        var currentCheckpointTime = DateTime.Now;
        if (currentCheckpointTime - _lastCheckpointTime > TimeSpan.FromSeconds(30))
        {
            Thread.Sleep(TimeSpan.FromSeconds(32));
            _lastCheckpointTime = DateTime.Now;
        }
    }
}

每次调用selenium都会触发新的tcp / ip端口,应该使用该方法(Checkpoint())。

答案 2 :(得分:0)

硒仓库中创建了一个问题: https://github.com/SeleniumHQ/selenium/issues/4162 里面有一些解决方法:

Option1

Option2