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:
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)?
The Selenium Grid is a testing tool which allows us to run our tests on different machines against different browsers. It is a part of the Selenium Suite which specialise in running multiple tests across different browsers, operating system and machines.
What is Selenium Grid? Selenium Grid is a smart proxy server that makes it easy to run tests in parallel on multiple machines. This is done by routing commands to remote web browser instances, where one server acts as the hub. This hub routes test commands that are in JSON format to multiple registered Grid nodes.
Selenium can use multi−threading in one browser with the help of TestNG framework. TestNG provides the feature of parallel execution which works on the concept of Java multi−threading. To execute tests based on various parameters, the TestNG has an XML file where we have the configurations.
There should only be one hub in a grid. The hub is launched only on a single machine, say, a computer whose O.S is Windows 7 and whose browser is IE. The machine containing the hub is where the tests will be run, but you will see the browser being automated on the node.
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 overSelenium 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.
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();
}
}
<?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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With