2016-10-07 8 views
1

Я написал инструмент автоматизации сети, используя Selenium WebDriver и geckodriver на Java. В настоящее время каждый раз, когда я выполняю задачу, создается новый объект FirefoxDriver.Каков правильный способ реализации «пула драйверов Selenium» в Java?

Теперь я хочу реализовать многопоточность. Первый подход, который пришел мне на ум, - это создать нечто вроде пула фиксированного размера - создать экземпляр объектов X FirefoxDriver при запуске, обернуть их объектом с флагом «inUse» и использовать один сингл для управления этими экземплярами.

Но это правильное решение? Это мой первый проект Selenium, и вся концепция для меня нова. Я не смог найти ответ на этот вопрос сам после нескольких дней поиска в Интернете и чтения документации. Я был бы очень признателен за вашу помощь!

+1

Вы считали, что используете что-то вроде TestNG и позволяете ему управлять бассейном? С помощью настроек вы можете ограничить количество потоков и т. Д., Которые разрешены. – JeffC

+0

Я еще не подумал об этом, спасибо за подсказку! Я буду рассматривать это для будущих задач автоматизации веб-сайтов. – saxum

ответ

1

Было бы совершенно разумно создать такой пул. Вместо того, чтобы писать свой собственный пул, я бы предложил использовать существующий общий пул, например классический Commons Pool или более современный бассейн spf4j.

Чтобы пул работал, ваш код должен надежно вернуть драйвер в пул после использования, иначе вы будете утечка драйверов (и, следовательно, всех экземпляров браузера!).

Поэтому я бы рассмотрел другой подход: посвятить драйвер каждой теме. Вы можете сделать это с помощью ThreadLocal:

private ThreadLocal<WebDriver> drivers = new ThreadLocal<WebDriver>() { 
    @Override 
    protected WebDriver initialValue() { 
     return new FirefoxDriver(); // or whatever 
    } 

    @Override 
    public void remove() { 
     WebDriver driver = get(); 
     if (driver != null) driver.close(); 
     super.remove(); 
    } 

    @Override 
    public void set(WebDriver value) { 
     throw new UnsupportedOperationException(); 
    } 
}; 

Это еще возможно просачиваться водителей, но только тогда, когда потоки умирают, не удаляя их значение из ThreadLocal. Если у вас есть фиксированный пул потоков, которые вы повторно используете, все будет в порядке.

Недостатком этого подхода является то, что вы получаете драйвер для каждого потока, который когда-либо использовал драйвер, даже если не каждый из этих потоков использует драйвер одновременно. Если у вас есть пул потоков, посвященных использованию драйверов, и не делая ничего другого, это не будет серьезной проблемой. Но если у вас есть пул потоков, которые выполняют много разных видов работы, это может быть.

+0

Но таким образом созданные окна браузера не будут переработаны, я думаю, что повторное использование созданных окон позволит сэкономить много времени. – saxum

+0

Было бы преимуществом при использовании подхода ThreadLocal вместо использования Executors.newFixedThreadPool (n) и порождать WebDriver внутри представленного потока? – saxum

+0

@saxum Пока каждый поток запускает несколько тестов, драйверы и браузеры будут повторно использоваться. Вам действительно нужно объединить это с исполнителем, чтобы это произошло. –