Parallel Execution with Selenium Grid

03 / Dec / 2015 by Vaibhav Singhal 5 comments

     Selenium Grid for Parallel Execution

When we say parallel test execution in Selenium is achieved by Selenium Grid than statement is partly incorrect.
  1. Testing Framework like testng is used for parallel test execution
  2. Selenium Grid is used for automated testing execution on Distributed systems parallely

Selenium Grid Concept

  1. In Selenium Grid architecture we have 1 Hub which acts as central controlling authority and connecting nodes. Nodes must be registered to Hub
  2. Consider node as port opened on machine (loacal or remote). Each node is capable to opening multiple browsers.
  3. On single machine we can have multiple nodes opened
  4. Grid Hub decides what tests needs to routed on which node, we can’t control them

Best Practices of Selenium Grid

  1. Single machine should open one node only
  2. Each node should run only single type of browser
  3. We need various driver objects for various threads to be run parallely, so create driver as ThreadLocal variable

Let consider an example what we would be achieving in our Grid:

SeleniumGrid

 

Start Hub and Nodes

  1. Download “Selenium Standalone Server” from “http://www.seleniumhq.org/download/” on all 3 machines
  2. Goto machine 1 and open command prompt.
  3. Navigate to location where jar is located.
  4. Start Hub by command:  java -jar selenium-server-standalone-2.48.2.jar -role hub
  5. Open browser and navigate to http://localhost:4444/grid/console and verify hub is started by checking below image.HubStarted
  6. Goto machine 2 and open command prompt
  7. Navigate to location where jar is located.
  8. Start Node by command: java -Dwebdriver.chrome.driver={path to chromedriver.exe}-jar selenium-server-standalone-2.48.2.jar -role webdriver -hub http://10.1.13.70:4444/grid/register -port 5560 -browser browserName=chrome,maxInstances=2,maxSession=2
  9. Goto machine 1 and in browser navigate to http://localhost:4444/grid/console and verify node is started by checking below image.SeleniumGridNode1
  10. Goto machine 3 and open command prompt.
  11. Navigate to location where jar is located.
  12. Start Node by command: java -jar selenium-server-standalone-2.48.2.jar -role webdriver -hub http://10.1.13.70:4444/grid/register -port 5557 -browser browserName=firefox,maxInstances=5,maxSession=2
  13. Goto machine 1 and in browser navigate to http://localhost:4444/grid/console and verify node is started by checking below image. SeleniumGridNode2
  14. Nodes can be opened for various settings like browser, platform, version.
  15. Now Selenium Hub and Nodes are created, lets make some @Test and execute them.
  16. Make Project on any machine, my project structure as below:PackageStructure
  17. Source code for files are given below.
  18. Execute testng.xml and execution will start parallely on both machines.

testng.xml

<?xml version="1.0" encoding="UTF-8"?>
<suite name="Parallel test suite" parallel="classes" thread-count="2">
	<test name="Regression 1">
	    <parameter name="myBrowser" value="firefox"/>
		<classes>
			<class name="myPackage.TestParallel" />
			<class name="myPackage.TestParallel" />
		</classes>
	</test>
	<test name="Regression 2">
	    <parameter name="myBrowser" value="chrome"/>
		<classes>
			<class name="myPackage.TestParallel" />
   			<class name="myPackage.TestParallel" />
		</classes>
	</test>

</suite>

BaseClass.java

package myPackage;

package myPackage;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;

public class BaseClass {

	//ThreadLocal will keep local copy of driver
	public static ThreadLocal<RemoteWebDriver> dr = new ThreadLocal<RemoteWebDriver>();

	@BeforeTest
	//Parameter will get browser from testng.xml on which browser test to run
	@Parameters("myBrowser")
	public void beforeClass(String myBrowser) throws MalformedURLException{

		RemoteWebDriver driver = null;

		if(myBrowser.equals("chrome")){
			DesiredCapabilities capability = new DesiredCapabilities().chrome();
			capability.setBrowserName("chrome");
			capability.setPlatform(Platform.WINDOWS);
			driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
		}
		else if(myBrowser.equals("firefox")){
			DesiredCapabilities capability = new DesiredCapabilities().firefox();
			capability.setBrowserName("firefox");
			capability.setPlatform(Platform.WINDOWS);
			driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
		}

		//setting webdriver
		setWebDriver(driver);

		getDriver().manage().window().maximize();
		getDriver().manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

	}

	public WebDriver getDriver() {
		return dr.get();
	}

	public void setWebDriver(RemoteWebDriver driver) {
		dr.set(driver);
	}

	@AfterClass
	public void afterClass(){
		getDriver().quit();
		dr.set(null);

	}

}

TestParallel.java

package myPackage;

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.firefox.FirefoxDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class TestParallel extends BaseClass {

	@Test
	public void test_01() throws InterruptedException, MalformedURLException{
		try{
			getDriver().get("http://www.w3schools.com/");

			getDriver().findElement(By.xpath("html/body/div[2]/div/a[4]")).click();

			//Wait intentially added to show parallelism execution
			Thread.sleep(10000);

			getDriver().findElement(By.xpath("//*[@id='gsc-i-id1']")).sendKeys("test");
			Thread.sleep(5000);

		}
		catch(Exception e){
			System.out.println(e);
		}
	}
}

FOUND THIS USEFUL? SHARE IT

comments (5)

  1. Dusitn

    I have pretty much the same setup as this, however, there are times where data from one thread ends up being entered in a field of another thread.

    Any idea how to correct this?

    Reply
  2. Soumya

    At present in our project we are using webdriver and writing selinium scripts in Excel,
    Can I run multiple scripts parallely in different browsers???
    Can I get complete details for that.

    Reply
  3. Andy Arias

    Hi Vaibhav, I wanna ask you what about if i want to have the base seleniu commands like .click or .get or .sendkeys in a separate class or in the same baseClass that you have created. Is there any issue when it run in parallel. I ask you this because I have tried something similar but I dont know why the instances get mixed in the execution. It is like driver is lost or I dont know.

    Thanks for the blog, It is so useful for me.

    Reply

Leave a comment -