Исчерпание порта tcp/ip с помощью selenium webdriver

Я работаю над набором тестов, используя веб-драйвер selenium (написанный на Python). Тестируемая страница содержит форму, которая изменяет отображаемые поля в зависимости от того, какое значение выбрано в одном из полей выбора. Это поле выбора содержит около 250 опций. У меня есть тест (запускаемый через нос, хотя это, вероятно, не имеет значения), который перебирает все параметры в поле выбора, проверяя, что в форме отображаются правильные поля для каждого выбранного параметра.

Проблема в том, что для каждого варианта вызывается через селен:

  • нажмите, чтобы выбрать вариант
  • find_element и is_displayed для 7 полей
  • find_elements для элементов в поле выбора
  • get_attribute и текст для каждой опции в поле выбора

Таким образом, получается (примерно) 250 * (7 * 2 + 1 + 2 * 250) или 128 750 различных запросов к серверу веб-драйвера, на котором выполняется тест, и все это в течение примерно 10 или 15 минут. В некоторых случаях это приводит к исчерпанию клиентского порта на машине, на которой выполняется тест. Все это выполняется через тестовую среду, которая абстрагируется от таких вещей, как анализ поля выбора, создание новых объектов страницы и некоторые другие вещи, поэтому оптимизация в тестовом коде означает либо хакнуть все это к черту, либо выбросить framework для этого теста и делать все вручную (что с точки зрения ремонтопригодности нашего тестового кода — плохая идея).

Некоторые идеи, которые у меня были для решений:

  • Попытка каким-то образом объединить или повторно использовать соединение с сервером веб-драйвера.
  • Как-то подправить конфигурацию urllib2 или httplib во время выполнения, чтобы соединения открывались по тайм-ауту селена или быстрее убивались
  • Независимый от системы (или, по крайней мере, реализуемый для всех систем с переключателем ОС или чем-то подобным) механизм активного отслеживания и закрытия портов, открываемых селеном.

Как я уже упоминал выше, я не могу много сделать, чтобы настроить способ анализа или обработки страницы, но у меня есть контроль над созданием подклассов/настройкой WebDriver или RemoteConnection любым удобным для меня способом. Есть ли у кого-нибудь какие-либо предложения о том, как подойти к любой из вышеперечисленных идей, или какие-либо идеи, которые я не придумал?


person Silas Ray    schedule 17.10.2012    source источник
comment
Есть несколько способов исправить это: 1. Используйте соединения проверки активности HTTP 1.1 и используйте их повторно. 2. увеличьте диапазон клиентских портов (см. документацию по вашей ОС, как в Windows использовать net tcp), 3. добавьте несколько спящих режимов, так как клиентские порты обычно можно повторно использовать примерно через 2 минуты.   -  person schlenk    schedule 17.10.2012
comment
@schlenk Я рассматривал эти варианты, но: 1. Не уверен, что мне нужно настроить во внутренних компонентах веб-драйвера, чтобы использовать поддержку активности 2. Увеличение максимального количества портов становится пользовательской конфигурацией для машин, на которых будут выполняться эти тесты, что делает их менее портативный и сложный в настройке (и изменение тайм-аута, по крайней мере, в Windows, может быть сделано только глобально из того, что я видел) 3. Этот тест уже занимает 10+ минут для относительно небольшой и простой проверки; добавление сна, особенно если они, по крайней мере, не запускаются динамически при обнаружении исчерпания портов, просто увеличивает время выполнения теста.   -  person Silas Ray    schedule 17.10.2012


Ответы (3)


Поскольку небольшое количество пластиковой взрывчатки решает проблему забывания ключей от дома, я реализовал решение. Я создал класс, который отслеживает список ресурсов и время их добавления в него, блокирует при достижении предела и удаляет записи, когда их метка времени превышает значение тайм-аута. Затем я создал экземпляр этой настройки класса с ограничением в 32768 ресурсов и тайм-аутом в 240 секунд, и мой тестовый фреймворк добавлял запись в список каждый раз, когда вызывается webdriver.execute() или несколько других действий (запросы БД, вызовы REST) выполняются. Это не особенно элегантно и довольно произвольно, но, по крайней мере, пока кажется, что мои тесты не вызывают исчерпания портов, не замедляя заметно тесты, которые раньше не вызывали исчерпания портов.

person Silas Ray    schedule 17.10.2012
comment
Три года спустя, боюсь, ничего не изменилось, и это настолько элегантно, насколько это возможно. +1 - person Erti-Chris Eelmaa; 18.07.2015

Была такая же проблема. Я также опубликую свое решение для будущих ссылок (хотя оно, скорее всего, не так хорошо, как ваше, но оно простое, и я не могу тратить на это свое время).

Я понятия не имею, почему 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;
        }
    }
}

Каждый вызов селена, который запускает новый порт tcp/ip, должен использовать этот метод (Checkpoint()).

person Erti-Chris Eelmaa    schedule 19.07.2015

В репозитории селена создана проблема: https://github.com/SeleniumHQ/selenium/issues/4162 с некоторым обходным решением внутри:

Вариант 1

Вариант 2

person Dima Dubyk    schedule 08.05.2019