Selenium Grid
Execute webdriver tests in Parallel using selenium Grid
In this tutorial we will see 'Parallel execution of tests' using selenium grid and execute tests on firefox and chrome browser.
We will register multiple nodes to the Hub and execute tests in parallel. In the below example we will register a node in the same local machine where hub is running and other node in remote machine.
We will register node 1 in local machine with the below command:
java -jar selenium-server-standalone-2.48.2.jar -role node -hub http://localhost:4444/grid/register
java -jar selenium-server-standalone-2.48.2.jar -role node -hub http://localhost:4444/grid/register
We will register node 2 with the below command in remote machine. In the below command, need to pass a parameter by passing JVM properties using the -D flag along with chrome driver path , so that when ever there is a request to execute in chrome driver, Hub will send the request to this node. And here we have to mention the IP address of the machine where the hub is running as we are starting this node in remote machine.
java -jar selenium-server-standalone-2.48.2.jar -role node -hub http://10.0.0.6:4444/grid/register -Dwebdriver.chrome.driver=.\chromedriver.exe
After executing the above command, console should look like below:
When a Hub receives request to execute test in Chrome browser and If we don't specify chrome driver path for node, it will throw an exception as "Exception: The path to the chromedriver executable must be set by the webdriver.chrome.driver system property; for more information, see http://code.google.com/p/selenium/wiki/ChromeDriver. The latest version can be downloaded from http://code.google.com/p/chromedriver/downloads/list".
Now when these two nodes are registered to the hub, hub console should look like below :
And the Grid console should look like below which shows configuration details of the nodes with IP address. In the below image below image Node 1 is running in Windows * machine (WIN8_1) and Node 2 is running in Windows7 machine.
Let us now take the example and execute tests in parallel.
In order to do this, we will create two classes which has multiple @Test methods in it. And a Browser class which invokes the remote webdriver based on the browser parameter that we pass in testng.xml file
First create a class as 'Browser.java'
package com.test;
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
public class Browser {
public static RemoteWebDriver getDriver(String browser) throws MalformedURLException {
return new RemoteWebDriver(new URL("http://10.0.0.6:4444/wd/hub"), getBrowserCapabilities(browser));
}
private static DesiredCapabilities getBrowserCapabilities(String browserType) {
switch (browserType) {
case "firefox":
System.out.println("Opening firefox driver");
return DesiredCapabilities.firefox();
case "chrome":
System.out.println("Opening chrome driver");
return DesiredCapabilities.chrome();
case "IE":
System.out.println("Opening IE driver");
return DesiredCapabilities.internetExplorer();
default:
System.out.println("browser : " + browserType + " is invalid, Launching Firefox as browser of choice..");
return DesiredCapabilities.firefox();
}
}
}
We will call 'getDriver' method which will intern call 'getBrowserCapabilities' based on browser parameter from the below two classes. If we pass 'chrome' as parameter, it is invoke chromedriver
Let us create a class as 'ParallelTestA.java' as below:
package com.test;
import java.net.MalformedURLException;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class ParallelTestA {
public static RemoteWebDriver driver;
public static String appURL = "http://www.google.com";
@BeforeClass
@Parameters({ "browser" })
public void setUp(String browser) throws MalformedURLException {
System.out.println("*******************");
driver = Browser.getDriver(browser);
driver.manage().window().maximize();
}
@Test
public void testGooglePageTitleInFirefox() {
driver.navigate().to(appURL);
String strPageTitle = driver.getTitle();
Assert.assertTrue(strPageTitle.equalsIgnoreCase("Google"), "Page title doesn't match");
}
@AfterClass
public void tearDown() {
if(driver!=null) {
System.out.println("Closing browser");
driver.quit();
}
}
}
Let us create a class as 'ParallelTestB.java' as below:
package com.test;
import java.net.MalformedURLException;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class ParallelTestB {
public static RemoteWebDriver driver;
public static String appURL = "http://www.google.com";
@BeforeClass
@Parameters({ "browser" })
public void setUp(String browser) throws MalformedURLException {
System.out.println("*******************");
driver = Browser.getDriver(browser);
driver.manage().window().maximize();
}
@Test
public void testGooglePageTitleInChrome() {
driver.navigate().to("http://www.google.com");
String strPageTitle = driver.getTitle();
Assert.assertTrue(strPageTitle.equalsIgnoreCase("Google"), "Page title doesn't match");
}
@Test
public void testSearchGoogle() {
System.out.println("Opening Google..");
driver.navigate().to(appURL);
driver.findElement(By.name("q")).sendKeys("Selenium Easy Grid Tutorials");
driver.findElement(By.name("btnG")).click();
}
@AfterClass
public void tearDown() {
if(driver!=null) {
System.out.println("Closing browser");
driver.quit();
}
}
}
Now to execute these tests, we need to create testng.xml file as below and set parallel="tests" with parameter browser for each test
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Main Test Suite" parallel="tests" verbose="1">
<test name="Grid firefox Test">
<parameter name="browser" value="firefox"/>
<classes>
<class name="com.test.ParallelTestA"/>
</classes>
</test>
<test name="Grid chrome Test">
<parameter name="browser" value="chrome"/>
<classes>
<class name="com.test.ParallelTestB"/>
</classes>
</test>
</suite>
Once we execute the above code, hub console will display information such as on 'number of nodes available', on which node it has started executing the tests etc.. as below :
There are many other parameters for browser settings that we can pass when registering node to hub. When ever we use -browser parameter, the default browsers will be ignored and only what we specify in command line will be used.
Example :
-browser browserName=firefox,version=30,maxInstances=5,platform=WIN8_1
After executing the above command, if you check the grid console, it will just show the browserName, browser version, Max instances (number of instances of same version of browser you can run over the Remote System) and the platform (OS running on the node) that we have used to register the node. Grid console looks like below :
If the remote machine has multiple versions of Firefox, We can map the location of each binary to a particular version on the same machine to execute with multiple versions as below:
How to Setup a Hub and Node for Selenium Grid
-browser browserName=firefox,version=40,firefox_binary=c:\Program Files\firefox30\firefox,maxInstances=3,platform=WINDOWS -browser browserName=firefox,version=41,firefox_binary=c:\Program Files\firefox40\firefox,maxInstances=3,platform=WINDOWS
How to Setup a Hub and Node for Selenium Grid
Selenium Grid allows us to execute our tests in multiple machines (physical / virtual) and multiple browsers with different versions, which dramatically speeds up test execution and helps in reducing total amount of time required for test execution.
For example, if we have a script that takes 100 minutes to execute sequentially , we could break that down to 10 short tests script run across 10 machines, and can complete them in 10 minutes without copying your test code to the other machine.
To get started with Selenium Grid, make sure you have Java installed and configured it and For selenium, you need to download selenium server and place it in a directory.
Selenium Grid hub/node can be configured in 2 different ways, one is by specifying command line parameters, and the other way is by specifying a JSON config file.
A grid consists of a single hub, and one or more nodes, Hub and Node are the two main elements that you come across when using grid
Hub the Hub is the central point which will receive all the test requests along with information on which browser, platform (i.e. WINDOWS, LINUX, etc) and where the test should be run. Based on the request received, it will distribute them to the registered nodes.
To start a hub with default parameters, we can run the below command from a command-line. Just navigate to the directory where your selenium jar file is available and execute the below statement. You can open command prompt from the same folder using 'Press Shift and Right Click' you see an option 'Open command window here'.
java -jar selenium-server-standalone-2.48.2.jar -role hub
In the above statement, we have started Hub using default parameters, So the default port will be 4444 and Hub listen for new requests is port 4444. This is why port 4444 was used in the URL for locating the hub. You can also change the default port, by adding the optional parameter -port when you run the command example: -port 5555.
After starting the hub, we can view the status of the hub by opening any browser window and navigating to: http://localhost:4444/grid/console . If you have used any other port, you need to mention that port value instead of default port 4444.
Nodes are where our tests will run, each Node is machine (can be a physical machine / virtual machine) that we register with the Hub, when we register Node, Hub will get to know about the node, and it will display browser and configuration details of the node that we used to register node with parameters.
Below is the command to register node with a Hub. If we are not specifying any parameters when starting node, it defaults to 5555 whenever "-role" option is provided and is not hub.
java -jar selenium-server-standalone-2.48.2.jar -role node -hub http://localhost:4444/grid/register
After executing above command, you should see something like below. When the hub is running in the same machine, we use ‘localhost’ for node. If Hub and Node are running on separate machines, we have to register Node using the hostname of the remote machine running the hub.
By default, when we start the node, it starts total 11 browsers : 5 Firefox, 5 Chrome and 1 Internet Explorer and it has same set of browsers for Selenium Remote Control (legacy). The maximum number of concurrent tests is default to 5.
We can change this and other browser settings as well by passing the parameters to each -browser switch (each switch represents a node based on your parameters). If you use the -browser parameter, the default browsers will be ignored and only what you specify command line will be used. The node can be configured in two different ways, One is by specifying command line parameters, the other is by specifying by a json file. We will discuss more in detail on these parameters in next articles.
For now, this is how it looks when we register without specifying any parameters
When you mouse hover on the browser icons, it will show config information, here "seleniumProtocol": "Selenium" which provides the mechanism for Selenium RC (Remote control / Selenium 1) and "seleniumProtocol": "WebDriver" is for Selenium WebDriver. After registering the node, You can see the difference in grid console as above.
We have done with starting the Hub and Registering Nodes with the Hub. Now we need to run our tests with Selenium Grid, For webdriver nodes, we need to use the RemoteWebDriver and DesiredCapabilities object to define which browser, version of the browser and platform (OS - Windows / LINUX etc) that we want to run our tests.
Based on preferences that we set in the DesiredCapabilities instance, the Hub will point our tests to a node that matches with these preferences. If we specify capabilities that do not exist on our grid then there will be no match and the test will fail to run.Why we need to use RemoteWebdriver Not the webdriver ?If we use driver (FirefoxDriver / ChromeDriver / or other) not RemoteWebDriver, it will just assume that the communication to the browser is local. Example: - Webdriver driver = new FirefoxDriver();Using this, driver will access Firefox browser which is available on the local machine.
If we use RemoteWebDriver, it requires us to specify where the Selenium Server is located and on which web browser we want to execute our tests. For example,
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), DesiredCapabilities.firefox());
Here in above statement , it is specified that Selenium Server is running on localhost with the default port 4444 and execute on firefox browser. In the same fashion, we can run selenium server on one machine as Hub and execute selenium tests on other machine by registering to the node by specifying parameters.
In the below example, Hub will point the test to a node which is running on the Windows machine (local machine) with Firefox browser as my node is executing in windows machine and capabilities specified is Only firefox browser.
package com.test;
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class GridExampleTest {
public RemoteWebDriver driver;
public static String appURL = "http://www.google.com";
@BeforeClass
public void setUp() throws MalformedURLException {
DesiredCapabilities capabilities = DesiredCapabilities.firefox();
driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capabilities);
driver.manage().window().maximize();
}
@Test
public void testGooglePageTitleInIEBrowser() {
System.out.println("*** Navigation to Application ***");
driver.navigate().to(appURL);
String strPageTitle = driver.getTitle();
System.out.println("*** Verifying page title ***");
Assert.assertTrue(strPageTitle.equalsIgnoreCase("Google"), "Page title doesn't match");
}
@AfterClass
public void closeBrowser() {
if (driver != null) {
driver.quit();
}
}
}
In the above test, BeforeClass method open firefox browser and , verifies page title of google. Once done, it will quit the remote webdriver.
Below is the testng.xml file :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Main Test Suite" verbose="1">
<test name="TestNG Grid">
<classes>
<class name="com.test.GridExampleTest"/>
</classes>
</test>
</suite>
After executing test as TestNG, you can view the console for details such as on which browser the tests are executed along with version and platform details if specified any.
Multi Browser, Cross Browser & Parallel Testing using TestNG
When the time comes to turn your site from mock-up to something fully functional, you’ll want to make sure that it works great for everyone visiting your site whether they’re using Internet Explorer, Firefox, or any other browser. Testing your website with multiple combinations of browsers is known as Cross Browser testing.
Your site will look different in different browsers. That’s because browsers understand some code slightly differently. Your designer should be testing to make sure that your site works well in all modern browsers. But as a tester we need to make sure that functionality should at least tested on Internet Explorer, Firefox, Safari & Google Chrome browser.
Multi Browser Testing using Selenium TestNG
In every project it is required to perform multi-browser testing to make sure that the functionality is working as expected with every browser to give equal user experience to all of the wide range of audience. It takes a considerable time to test everything on every browser and when we have used automation to reduce the testing efforts then why don’t we perform the multi-browser testing using automation. TestNG gives us functionality to perform same test on different browsers in a simple and easy way.
How to do it…
1)Create your Script to test a LogIn application using TestNG class.
2) Pass ‘Browser Type’ as parameters using TestNG annotations to the before method of the TestNG class. This method will launch only the browser, which will be provided as parameter.
3) Create a TestNG XML for running your test. Configure the TestNG XML for passing parameters i.e. to tell which browser should be used for Running the Test.
Note: You can set any number of Browsers here and just for the example purpose I have set up only two main browsers.
4) Now it’s time to run the xml. Run the test by right click on the testng.xml file and select Run As > TestNG Suite.
Note: TestNg will execute the test one by one. You may like to perform parallel tests, next topic will cover that.
Parallel Tests using TestNG
Using the feature provided by TestNG for Parallel Executions. just take the above example for Sign In application with two different browsers. This time all we want is to execute test in both browsers simultaneously.
Now just set the ‘parallel‘ attribute to ‘tests‘ in the above used xml and give a run again. This time you will notice that your both browsers will open almost simultaneously and your test will run in parallel.
Note: You may see some intermittent issues using parallel testing. I will not recommend you this rather run one by one only.
Comments
Post a Comment