首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在并行任务中跟踪死WebDriver实例

在并行任务中跟踪死WebDriver实例
EN

Stack Overflow用户
提问于 2012-04-26 04:05:53
回答 2查看 1.5K关注 0票数 2

我看到了一些使用Selenium WebDriver并行化嵌套循环网络压力测试的死实例怪怪的,简单的例子是,比如说,点击300个独特的页面,每个页面都有100个印象。

我正在“成功地”获得4-8个WebDriver实例,使用ThreadLocal<FirefoxWebDriver>来隔离每个任务线程,并在ParallelOptions实例上使用MaxDegreeOfParallelism来限制线程。我只对外部循环(页面集合)进行分区和并行化,并在每个分区的“长时间运行任务”方法的开头检查ThreadLocal<>容器上的ThreadLocal<>。为了便于以后的清理,我将每个新实例添加到由线程id键确定的ConcurrentDictionary中。

无论我使用什么并行化或分区策略,WebDriver实例偶尔都会执行以下操作之一:

  • 启动,但不要显示URL或运行印象
  • 发射,运行任意数量的印象很好,然后只是坐在闲置的某个点。

当这两种情况都发生时,并行循环最终似乎注意到线程没有执行任何操作,并且产生了一个新的分区。如果n是允许的线程数,这将导致n个生产线程的时间仅为50-60%。

清理工作在最后仍然很好;可能有2n个开放浏览器,或者更多,但是生产性和非生产性的浏览器都会被清理干净。

有没有办法监视这些无用的WebDriver实例,以及( a)立即清除它们,再加上b)立即获得并行循环来替换任务段,而不是像现在这样落后几分钟?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-08 16:00:33

由于没有OnReady事件,也没有IsReady属性,所以在创建每个实例之后,我通过休眠线程来解决这个问题。这样做似乎给了我100%持久的、功能良好的WebDriver实例。

多亏了您的建议,我在开源项目Webinator中实现了IsReady功能。如果需要,可以使用它,或者使用下面列出的代码。

我尝试过实例化25个实例,它们都是功能性的,因此我对算法非常有信心(我利用HtmlAgilityPack来查看元素是否存在,但为了简单起见,我将跳过它):

代码语言:javascript
复制
public void WaitForReady(IWebDriver driver)
{
    var js = @"{ var temp=document.createElement('div'); temp.id='browserReady';" +
             @"b=document.getElementsByTagName('body')[0]; b.appendChild(temp); }";
    ((IJavaScriptExecutor)driver).ExecuteScript(js);

    WaitForSuccess(() =>
    {
        IWebElement element = null;
        try
        {
            element = driver.FindElement(By.Id("browserReady"));
        }
        catch
        {
            // element not found
        }

        return element != null;
    },
    timeoutInMilliseconds: 10000);

    js = @"{var temp=document.getElementById('browserReady');" +
         @" temp.parentNode.removeChild(temp);}";
    ((IJavaScriptExecutor)driver).ExecuteScript(js);
}

private bool WaitForSuccess(Func<bool> action, int timeoutInMilliseconds)
{
    if (action == null) return false;

    bool success;
    const int PollRate = 250;
    var maxTries = timeoutInMilliseconds / PollRate;
    int tries = 0;
    do
    {
        success = action();
        tries++;
        if (!success && tries <= maxTries)
        {
            Thread.Sleep(PollRate);
        }
    }
    while (!success && tries < maxTries);
    return success;
}

假设浏览器响应javascript函数并找到元素,那么它可能是一个可靠的实例,可以使用。

票数 1
EN

Stack Overflow用户

发布于 2012-07-20 19:23:56

我也有类似的问题。事实证明,WebDriver没有找到开放端口的最佳方法。正如所描述的这里,它在端口上获得一个系统范围的锁,找到一个开放端口,然后启动实例。这可能会使您尝试启动端口的其他实例挨饿。

我通过在ThreadLocal<IWebDriver>的委托中直接指定一个随机端口号来解决这个问题,如下所示:

代码语言:javascript
复制
        var ports = new List<int>();
        var rand = new Random((int)DateTime.Now.Ticks & 0x0000FFFF);

        var driver = new ThreadLocal<IWebDriver>(() =>
        {
            var profile = new FirefoxProfile();
            var port = rand.Next(50) + 7050;
            while(ports.Contains(port) && ports.Count != 50) port = rand.Next(50) + 7050;
            profile.Port = port;
            ports.Add(port);
            return new FirefoxDriver(profile);
        });

这对我来说非常一致,尽管如果你最终使用列表中所有的50种都是未解决的问题,这是个问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10327095

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档