java - 多线程 Selenium WebDriver 与 Selenium Grid

标签 java multithreading selenium selenium-webdriver selenium-grid

我是 Selenium 的新手,我正在使用 Selenium 在保持 session 的同时导航到同一网站的多个页面。我可以通过以下两种方式创建 Controller :

  1. Controller 在多线程环境中启动 Selenium WebDriver(每个线程 1 个驱动程序实例,因为 WebDriver 不是线程安全的。引用:Selenium Grid, how to utilize WebDriver with ThreadSafeSeleniumSessionStorage.session())
  2. Controller 使用Selenium Grid

我了解 Selenium Grid 通过使用中心节点概念支持分布式执行;但与选项 1 相比,我将获得的主要好处是什么。

我看到有人使用选项 1,但遇到了一些问题。引用:Multiple WebDriver instances in Selenium without Grid?

是否建议在多线程环境中使用 Grid over Selenium WebDriver?如果是这样,为什么? 此外,Selenium Grid 是否会负责清理其节点中任何陈旧的浏览器实例(开箱即用)?

最佳答案

我觉得您误解了 WebDriver、Grid 和多线程环境的用途。

Selenium WebDriver 只是一个测试框架,可以在浏览器上启动测试。它使用 geckodriver 和 chromedriver 等驱动程序打开(和关闭)浏览器实例,然后使用操作命中这些实例。

Selenium Grid 是一个独立的服务器,它将在一个节点上远程运行您的 WebDriver 测试并返返回告。因此,如果您想使用另一台机器资源来运行您的测试套件,您将能够这样做。它还允许您通过为每个节点分配一个节点来组合多台机器资源,Selenium Grid 将平均分配您的测试。


关于你关于多线程的问题,

Is it recommended to use Grid over Selenium WebDriver in a multithreaded environment?

Grid 只是 WebDriver 的远程运行器。 WebDriver 是测试框架。我假设您的目标是通过并行运行测试来减少测试套件的运行时间?并行测试可以使用 WebDriver 在本地机器上完成,也可以在 Selenium Grid 上配置。根据我的经验,我在本地机器上比在 Grid 上更幸运,但两者本质上都面临着同样的问题。 使用 WebDriver 进行并行测试的主要危险是 thread-safety . JUnit 4.7 及 Test-NG RELEASE 允许并行测试。 我强烈建议为此目的使用 Test-NG 而不是 JUnit。

为防止并发问题,您的主要目标是将所有共享资源隔离在每个线程中。次要目标是将所有变量的范围限制在其方法内。这可以使用 ThreadLocal 的静态实例来完成在同步方法中强制卡住驱动程序实例的初始化也非常有用。

创建资源

public class DriverFactory {

    private static String grid = "http://localhost:4444/wd/hub";
    public static ThreadLocal<WebDriver> drivers = new ThreadLocal<WebDriver>();

    public static synchronized void newDriver() {
        ChromeOptions options = new ChromeOptions(); // Assuming Chrome use
            options.addArguments("--start-maximized");

        // USE THIS FOR LOCAL
        // tlDriver.set(new ChromeDriver(options));

        // USE THIS FOR GRID
        try {
            drivers.set(new RemoteWebDriver(new URL(grid),options));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

    public static synchronized WebDriver getDriver() {
        return drivers.get();
    }
}

测试类

public class GoogleTest {
    @BeforeMethod
    public void setup() {
         DriverFactory.newDriver();
    }

    @Test
    public void test1() {
        WebDriver driver = DriverFactory.getDriver();
        driver.navigate().to("https:\\www.google.com");
        Assert.assertEquals(driver.getTitle(), "Google");
    }

    @Test
    public void test2() {
        WebDriver driver = DriverFactory.getDriver();
        driver.navigate().to("https:\\www.google.com");
        Assert.assertEquals(driver.getTitle(), "Google");
    }


    @AfterMethod
    public void tearDown() {
        WebDriver driver = DriverFactory.getDriver();
        driver.quit();
    }
}

TestNG.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<!-- thread-count should be = to maxSessions on your Grid -->
<suite name="Whatever" parallel="methods" thread-count="5">
  <test name="Sample">
    <classes>
      <class name="GoogleTest"/>
    </classes>
  </test>
</suite>

来源:Making your Tests Thread-Safe , Full Guide
使用的版本: TestNG 6.14.3、Selenium 3.11、Selenium Grid 3.14.3

Also, would Selenium Grid take responsibility of cleaning any stale browser instances in its nodes (out of the box)?

Selenium Grid 具有超时和浏览器超时功能,可以释放节点并关闭浏览器实例。尽管根据我的经验,我会恳请您控制测试用例中的任何预期超时,并让 WebDriver 关闭浏览器实例,而不是 Selenium Grid。你真的想防止这种情况发生并消除所有意外挂起的原因。测试套件旨在提供快速反馈,并且仅在故障指示实际故障时才有用,而不仅仅是脏测试套件。陈旧的节点/浏览器也会迫使你不得不不断地重置你的网格+节点,这是一个主要的损害。

关于java - 多线程 Selenium WebDriver 与 Selenium Grid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35954465/

相关文章:

java - 如何使用 PowerMock 模拟 FileInputStream?

java - 邮件被防火墙阻止

java - 如何在 Java9 模块中使用 3rd 方库?

java - JSF p :calendar in p:dataTable: How to get the row of p:ajax dateSelect event

java - 如何只有一个驱动程序可以用作Webdriver或Appiumdriver

selenium - 使用 selenium ide 将随机值插入文本区域

python - Selenium,通过 Xpath 获取元素 - 仅获取页面上的最后 60 个元素

java - 超时后中止 countDownLatch.await()

multithreading - 为什么 Rust playground 不会为线程产生不同的结果?

c - 串行通信 C/C++ Linux 线程安全吗?