Distributed Test Execution in Selenium Using Selenium-Grid
Set up the node and hub machines in Selenium-Grid that will allow you to perform distributed testing.
Join the DZone community and get the full member experience.
Join For FreeSelenium-Grid Overview
Selenium-Grid allows your tests to execute on different machines/platforms against different browsers in parallel. Essentially, it supports distributed test execution. Selenium-Grid allows the execution of tests in a distributed test execution environment and works on hub-node architecture, where the hub is the machine where the actual test scripts are designed and exists and the node is the machine where the execution of the test script is done.
Note: While one hub can be configured with multiple nodes, each node can be configured to one hub only.
Hub Machine
The hub acts as a server which provides a centralized infrastructure for test machines. It is the primary point of test requests which need to be distributed to the right nodes.
How to Start the Hub
- Download the Selenium server which includes grid capabilities from the SeleniumHQ website. Save the server library in the local drive and open the command line/terminal.
- To start the hub machine, use the below command with default settings.
java -jar selenium-server-standalone-3.141.59.jar -role hub
3. To start the hub machine with customized settings, add the properties in the JSON file and load the JSON file through the command. Save the file as hubConfig.json.
{
"_comment" : "Configuration for Hub - hubConfig.json",
"host": ip,
"maxSession": 5,
"port": 4444,
"cleanupCycle": 5000,
"timeout": 300000,
"newSessionWaitTimeout": -1,
"servlets": [],
"prioritizer": null,
"capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
"throwOnCapabilityNotPresent": true,
"nodePolling": 180000,
"platform": "WINDOWS"
}
java -jar selenium-server-standalone-3.141.59.jar -role hub -hubConfig hubConfig.json -debug
Node Machine
The hub uses node machines (remote machines) to execute the test scripts. The hub can be configured with multiple nodes, and multiple nodes can have different platforms and can run tests on multiple browsers. Node machine and the hub need not have the same platform.
How to Start the Node
Download the selenium server which includes grid capabilites from SeleniumHQ website. Save the server library in the node machine and open command line/terminal.
- Start the nodes with respective browsers by passing the arguments as
–role node –hub http://ipaddressofhub:4444/grid/register -port 5432
through command line arguments as shown below.
java -Dwebdriver.chrome.driver="path_to_chrome_driver/chromedriver.exe" -jar
selenium-server-standalone-3.141.59.jar –role node -hub
http://ipaddressofhub:4444/grid/register -port 5432
java -Dwebdriver.gecko.driver="path_to_gecko_driver/geckodriver.exe" -jar
selenium-server-standalone-3.141.59.jar –role node -hub
http://ipaddressofhub:4444/grid/register -port 5432
java -Dwebdriver.ie.driver="path_to_gecko_driver/IEDriverServer.exe" -jar
selenium-server-standalone-3.141.59.jar –role node -hub
http://localhost:4444/grid/register -port 5566
3. To start node machine with customized settings, add the properties in the JSON file and load the JSON file through the command. Save the file as nodeConfig.json.
{
"capabilities": [
{
"browserName": "chrome",
"maxInstances": 5,
"platform": "WINDOWS",
"webdriver.chrome.driver": "C:/Selenium/Drivers/chromedriver.exe"
},
{
"browserName": "firefox",
"maxInstances": 5,
"platform": "WINDOWS",
"webdriver.gecko.driver": "C:/Selenium/Drivers/geckodriver.exe"
},
{
"browserName": "internet explorer",
"maxInstances": 1,
"platform": "WINDOWS",
"webdriver.ie.driver": "C:/Selenium/Drivers/IEDriverServer.exe"
}
],
"configuration": {
"_comment" : "Configuration for Node",
"cleanUpCycle": 2000,
"timeout": 30000,
"proxy": "org.openqa.grid.selenium.proxy.WebDriverRemoteProxy",
"port": 5432,
"host": ipaddrdessofhub,
"register": true,
"hubPort": 4444,
"maxSession": 5
}
}
Designing Test Scripts - Hub Machine
- Automate the login functionality for Demo Web Shop on different machines and different browsers by creating a
RemoteWebDriver
instance with Node Address URL and Desired Capabilities. Create a Maven project and add the following dependencies in the pom.xml file.
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>
/**
* @author aswani.kumar.avilala
*/
package com.test;
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.By;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class HubNodeTest {
WebDriver driver;
@BeforeTest
@Parameters("node")
public void beforeTest(String value) throws MalformedURLException
{
DesiredCapabilities ds=DesiredCapabilities.chrome();
ds.setPlatform(Platform.ANY);
driver=new RemoteWebDriver(new URL(value),ds);
driver.manage().window().maximize();
driver.get("http://demowebshop.tricentis.com/login");
}
@AfterTest
public void afterTest()
{
driver.close();
}
@Test(dataProvider="dp1")
public void testValidUsersDemoWebShop(String username,String password)
{
driver.findElement(By.id("Email")).sendKeys(username);
driver.findElement(By.id("Password")).sendKeys(password);
driver.findElement(By.xpath("//input[@value='Log in']")).click();
driver.findElement(By.linkText("Log out")).click();
driver.findElement(By.linkText("Log in")).click();
}
@DataProvider(name="dp1")
public Object[][] provideData()
{
// to connect to excel & convert to object 2d array
return ReadExcel.testExtractDataExcel();
}
}
- Created data in Excel with different users to test.
- Read the data from Excel using the Aache POI Library. Download the library from the mvn repository
/**
* @author aswani.kumar.avilala
*/
package com.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ReadExcel{
public static Object[][] testExtractDataExcel()
{
System.out.println(System.getProperty("user.dir"));
File file=new File("src\\test\\resources\\Book1.xlsx");
Object[][] obj=null;
try(InputStream is=new FileInputStream(file)){
XSSFWorkbook workbook=new XSSFWorkbook(is);
XSSFSheet sheet1=workbook.getSheet("Sheet1");
obj=new Object[sheet1.getLastRowNum()][];
for(int i=1;i<=sheet1.getLastRowNum();i++)
{
obj[i-1]=new Object[sheet1.getRow(i).getPhysicalNumberOfCells()];
for(int j=0;j<sheet1.getRow(i).getPhysicalNumberOfCells();j++)
{
obj[i-1][j]=sheet1.getRow(i).getCell(j).getStringCellValue();
}
System.out.println();
}
workbook.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return obj;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite" parallel="tests">
<test name="Test1">
<parameter name="node"value="http://10.116.17.121:8706/wd/hub"/>
<classes>
<class name="com.test.HubNodeTest" />
</classes>
</test>
<test name="Test2">
<parameter name="node" value="http://10.116.17.135:7788/wd/hub"/>
<classes>
<class name="com.test.HubNodeTest" />
</classes>
</test>
<test name="Test3">
<parameter name="node" value="http://10.116.17.114:1234/wd/hub"/>
<classes>
<class name="com.test.HubNodeTest" />
</classes>
</test>
<test name="Test4">
<parameter name="node" value="http://10.116.17.110:4591/wd/hub"/>
<classes>
<class name="com.test.HubNodeTest" />
</classes>
</test>
</suite> <!-- Suite -->
Conclusion
The main advantage of the Selenium Grid is that it reduces the test execution time. Using the RemoteWebDriver API we can achieve a distributed execution test environment in Selenium. To set up the environment, we need to configure hub machine and node machines. The node machine IP address and the desired capabilities are passed as arguments to the RemoteWebDriver instance to launch WebDriver on remote machines to achieve distributed test execution.
Opinions expressed by DZone contributors are their own.
Comments