我有我的应用程序自动化,它有大约 70 多个脚本,并针对对其他应用程序开放的 Selenium Grid 运行。
我的问题是,有没有用于 WebDriver 的连接池 api?这样我就可以在我的脚本中有效地重新使用 webdriver 对象。我不希望我的脚本等待 IE 插槽并在无法获得时因超时错误而失败。
另外,我相信它会提高脚本执行的性能。
谢谢。
我有我的应用程序自动化,它有大约 70 多个脚本,并针对对其他应用程序开放的 Selenium Grid 运行。
我的问题是,有没有用于 WebDriver 的连接池 api?这样我就可以在我的脚本中有效地重新使用 webdriver 对象。我不希望我的脚本等待 IE 插槽并在无法获得时因超时错误而失败。
另外,我相信它会提高脚本执行的性能。
谢谢。
我们的测试非常小而且速度非常快,以至于 webdrivers 的实例化时间比测试要长。所以我们汇集了网络驱动程序,就像@premganz 建议的那样,但是使用了 Apache Commons Pool。我们考虑编写自己的 webdriver 列表管理池,但发现使用完善的 Apache 池易于实现、健壮且可扩展。我们的测试同时运行 80 多个 WebDriver。
示例 WebdriverFactory:
public class WebdriverFactory extends BasePooledObjectFactory<RemoteWebDriver> {
private FirefoxOptions firefoxOptions = new FirefoxOptions();
public WebdriverFactory(boolean headless, int implicit_timeout_seconds) {
super();
firefoxOptions.setHeadless(headless)
.setPageLoadStrategy(PageLoadStrategy.EAGER)
.setLogLevel(FirefoxDriverLogLevel.ERROR);
}
@Override
public RemoteWebDriver create() {
FirefoxDriver webDriver = new FirefoxDriver(firefoxOptions);
webDriver.manage()
.timeouts()
.implicitlyWait(implicit_timeout_seconds, TimeUnit.SECONDS);
return webDriver;
}
/**
* Use the default PooledObject implementation.
*/
@Override
public PooledObject<RemoteWebDriver> wrap(RemoteWebDriver webDriver) {
return new DefaultPooledObject<>(webDriver);
}
/**
* When a webdriver is returned to the pool, clean it up.
*/
@Override
public void passivateObject(PooledObject<RemoteWebDriver> webDriver) {
WebDriver driver = webDriver.getObject();
try {
// close all tabs except the first
String originalHandle = driver.getWindowHandle();
for(String handle : driver.getWindowHandles()) {
if (!handle.equals(originalHandle)) {
driver.switchTo().window(handle);
driver.close();
}
}
driver.switchTo().window(originalHandle);
} catch (Exception e) {
// ...
} finally {
// ensure session data is not re-used
driver.manage().deleteAllCookies();
}
}
@Override
public boolean validateObject(PooledObject<RemoteWebDriver> webDriver) {
return true;
}
@Override
public void activateObject(PooledObject<RemoteWebDriver> webDriver) throws Exception {
}
}
我同意 WebDriver 池可以提高应用程序的性能。另一方面,如果您使用的是 selenium webdriver,则驱动程序将变为有状态的,从而使其可重用性降低。我做了这样的逻辑:
创建一个驱动程序工厂,它包装一个大小为 10 的链表(它实现了一个列表和一个队列)。
当被要求提供一个实例时,从列表中提供中间 (i==5) 一个
使用另一个线程回收队列中的驱动程序,从头部删除驱动程序并在尾部添加新驱动程序。
这样您就可以实现一个不断回收的池,并且您的代码不必阻塞在 driver.create 或 driver.quit 上。