Multi threaded Selenium WebDriver vs Selenium Grid
Asked Answered
A

1

7

I am a newbie to Selenium and am using Selenium to navigate to multiple pages of the same website simultaneously while maintaining a session. I can create a controller in the following 2 ways:

  1. The controller initiates Selenium WebDriver in a multithreaded environment (1 driver instance per each thread, as WebDriver is not thread-safe. Reference: Selenium Grid, how to utilize WebDriver with ThreadSafeSeleniumSessionStorage.session())
  2. Controller uses Selenium Grid

I understand Selenium Grid supports distributed execution by using a hub-node concept; but what are main benefits I would be getting as compared to Option 1.

I see people using Option 1, but facing some issues. Reference: Multiple WebDriver instances in Selenium without Grid?

Is it recommended to use Grid over Selenium WebDriver in a multithreaded environment? If so, why? Also, would Selenium Grid take responsibility of cleaning any stale browser instances in its nodes (out of the box)?

Antoneantonella answered 12/3, 2016 at 6:18 Comment(1)
It all depends. Can you clarify what you're trying to achieve, first: are you trying to test multiple browsers / platforms; are you attempting to do load testing; are you simply trying to reduce the duration of an existing test suite; and how many sessions do you plan/hope to have running at once (per machine)?Aboral
P
6

I feel like your misunderstanding the purposes of WebDriver, Grid and a multi-threaded environment.

Selenium WebDriver is just a test framework that kicks off tests onto a browser. It uses drivers such as geckodriver, and chromedriver to open (and close) browser instances and then hits those instances with actions.

Selenium Grid is a stand-alone server that will run your WebDriver tests remotely on a node and reports back. So if you wanted to use another machines resources to run your test-suite you would be able to do so. It also allows you to combine multiple machines resources by assigning each a node and Selenium Grid will distribute your tests evenly.


As far as your questions about multi-threading,

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

Grid is just a remote-runner of WebDriver. WebDriver is the test-framework. I assume your goal is to reduce your test-suite's run-time by running tests in parallel? Parallel testing can be done on your local machine using WebDriver or can be configured on a Selenium Grid. In my experience, I have gotten more lucky on my local machine than on Grid but both essentially face the same problem. The main danger for parallel testing using WebDriver is thread-safety. JUnit 4.7 onwards and Test-NG RELEASE allow for parallel testing. I highly suggest using Test-NG instead of JUnit for this purpose.

To prevent concurrency issues, your main goal will be to make all your shared resources isolated within each thread. A secondary goal is to limit the scope of all variables to its method. This can be done using a static instance of ThreadLocal It is also really useful to force the initializing of driver instances to be frozen in synchronized methods.

Creating Resources

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();
    }
}

Test Class

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>

Source: Making your Tests Thread-Safe, Full Guide
Versions Used: 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 has timeout and a browserTimeout features to free up nodes and close browser instances. Although in my experience I would implore you to control any expected timeouts in your test-cases and have WebDriver close the browser instance, not Selenium Grid. You really want to prevent this from happening and eliminate all causes of un-expected hanging. Test-suites are designed to be quick feedback and are only useful if failures are indicative of an actual failure, not just a dirty test-suite. Also stale nodes/browsers can force you to have to constantly reset your grid + nodes which is a major detriment.

Phytology answered 13/11, 2018 at 7:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.