Parallel Execution with Selenium Grid

03 / Dec / 2015 by Vaibhav Singhal 13 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 -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 -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 (13)

  1. venkat

    Hi Vaibhav,
    Nice blog. would like to know the versions of firefox, ie, and chrome browsers you have used while using selenium grid. Thank you.

    Reply
  2. saurabh

    Hi,
    I understood the grid concept by this.But the example which you have given i tried with that,it is not executing it parallel.
    First it is executing it in firefox and after completing it’ll execute it in chrome.
    Please help me

    Reply
  3. Parag Mangal

    Hi Vaibhav,
    Im new to selenium grid testing, however I have read many stuff on internet regarding this. There is not much stuff regarding ruby and selenium grid on internet. I was working with the selenium grid and ruby test cases. Now I have to run these test cases over the grid. I am able to create the grid. But after it I don’t have anything like testng in java for ruby. So Im unable to assign test cases to nodes. Please look at it with ruby. may be I can get a big help. Thanks

    Reply
    1. sandhya s

      Hi Vaibhav,
      Me too facing same problem. We are using Keyword Driven Framework with Ruby on Rails. Its fine till setting up the nodes but problem starts when assigning the Test cases in ruby to the grid. Can anyone please provide the solution ?? That would be much helpful.

      Reply
  4. Jones

    Informative post about Selenium Grid
    When I started learning then I understood it has got really cool stuff.
    I can vouch webdriver has proved the best feature in Selenium framework.
    thanks a lot for taking a time to share a wonderful article.

    Reply
  5. Daragh

    I keep getting a “java.lang.NullPointerException” on the below line. I have everything setup as per required. getDriver().get(“http://www.w3schools.com/”);

    Reply
  6. 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
  7. 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
  8. 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
    1. Ankit

      Hi Andy,

      You can create a separate helper class for the click, sendkeys action and then you can call it in main test class. For example if i need to find a webelement by id then i can make separate function FindElementById(String id) { driver.findElementById(“ID”)} and then can call it in test class FindElementById(“Email”); and so on. You can create various helper methods for you to avoid redundancy. Hope it helps!

      Reply

Leave a comment -