可在内部循环运行

时间:2019-03-20 20:06:03

标签: java selenium web-scraping selenium-chromedriver

我想在线程的for循环内运行代码,因为它几乎可以执行相同的操作,但适用于不同的页面(使用selenium webdriver)。我的问题是,我的计数器变量不能增加,因为它必须是最终变量...

这是我的测试代码,但变量“ tabCount”始终保持为i。

// scrape over all tabs and get data in threads
        for (int i = 0; i < tabs.size(); i++) {
            final int tabCount = i;

            Runnable r = () -> {
                webDriver.switchTo().window(tabs.get(tabCount));
                System.out.println(webDriver.getTitle());
            };

            threadPool.execute(r);
        }

        threadPool.shutdown();
        try {
            threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

有人可以帮助我在chromedriver的每个标签页中并行执行相同的操作吗?

1 个答案:

答案 0 :(得分:3)

我认为您走错了兔子洞。查看您的代码:

webDriver.switchTo().window(tabs.get(tabCount));
System.out.println(webDriver.getTitle());

您希望webDriver 切换到另一个窗口。然后在该选项卡上执行某些操作。但是,如果第一行和第二行之间存在线程的上下文切换该怎么办?

如:

  • 线程A:确实webDriver.switchTo()
  • 线程B:webDriver.switchTo()
  • 线程A:打印页面标题

很显然,这将导致比赛条件!当然,您可以添加某种锁定/同步,以便线程始终切换到选项卡并执行其工作,而另一个线程无法同时更新webDriver对象。但这基本上可以序列化您的测试。

长话短说:webDriver对象具有内部状态。您的方法完全忽略了这一事实,因此无法预测代码将要执行的操作。

一个简单的解决方法是在每个线程中实例化一个WebDriver实例,如注释中所建议。除此之外,有关如何以不同于硒“思考”并行测试的方式的想法,请参见here