How to do Multiple Browser Parallel Testing in a selenium TestNG project
Tags: automation, selenium, testng, xml
Published: 2021-05-26 19:17:03

##Topics to be covered in this article.
*What is Parallel Testing?
What is testing.xml?
Adding Dependencies to the pom.xml file
Creating a Java class
Creating a testing.xml file
Demo Test Run
Thread count*

###What is Parallel Testing?

In parallel testing, we test different modules or applications on multiple browsers in parallel rather than one by one.

The parallel test execution is different from sequential testing, where we test different modules or functionalities one after the other.
 
This approach of testing is very time-consuming.
Parallel testing helps to reduce execution time and efforts and results in a faster time to delivery. It proves to be handy specifically in case of cross browser testing.

So in this article we are going to work with Selenium, TestNG using testing.xml file. And practically discuss about parallel testing, parallel thread count and how to run tests in multiple browsers in parallel.

Then lets go for it…

###What is testing.xml?

If you are using TestNG as your testing framework in your selenium project then **testing.xml** file is a configuration file in TestNG and we can use this file to set some execution settings to our tests.

Basically **testing.xml** file is used to control the execution of a TestNG test like what packages/ classes/ methods should included, what should not be excluded, setting dependencies and so on…

So lets start a simple test using TestNG by adding dependencies in the *pom.xml* file.

###Adding Dependencies to the pom.xml file

First create a maven project and name it as **Testing.XML.** Then add following dependencies to the *pom.xml* file.

First copy the selenium dependency and set it in the *pom.xml* file.
https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java/3.141.59
```javascript
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
</dependency>
``` 

Copy the TestNG dependency and set it in the *pom.xml* file.
https://mvnrepository.com/artifact/org.testng/testng
```javascript
<! —  https://mvnrepository.com/artifact/org.testng/testng →
<dependency>
 <groupId>org.testng</groupId>
 <artifactId>testng</artifactId>
 <version>7.4.0</version>
 <scope>test</scope>
</dependency>
``` 

As well as set the WebDriver maven dependency for Chrome and Firefox drivers.
https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager/4.4.3
```javascript
<dependency>
    <groupId>io.github.bonigarcia</groupId>
    <artifactId>webdrivermanager</artifactId>
    <version>4.4.3</version>
</dependency>
``` 

That all we have to do as prerequisites and we are good to go…

###Creating a Java class

Create a new Java class called **test.java** inside the package **“test”.**

For a simple test lets try to navigate to “www.ebay.com” , validate the site based on title and search something and hit enter.

Paste this code into your project and run it as a TestNG Test.
```javascript
package test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import io.github.bonigarcia.wdm.WebDriverManager;
public class DarazSearchTestNG {
 
 WebDriver driver = null;
 static String expectedTitleebay ="Electronics, Cars, Fashion, Collectibles & More | eBay";
 
 @BeforeTest
 public void setUp(){
 String browserName = "chrome";
  if(browserName.equalsIgnoreCase("chrome")) {
  //initializing and starting the Chromebrowser
  WebDriverManager.chromedriver().setup();
  driver = new ChromeDriver();
 }else if(browserName.equalsIgnoreCase("firefox")) { 
  //initializing and starting the Chromebrowser  
  WebDriverManager.firefoxdriver().setup();   
  driver = new FirefoxDriver();  
 }
}
@Test
 public void test1() throws InterruptedException {
 
  //maximize the window 
  driver.manage().window().maximize();
  driver.get("https://www.ebay.com");
  Thread.sleep(1000);
  
  String actualTitle = driver.getTitle();
  Assert.assertEquals(actualTitle, expectedTitleebay);
  
  driver.findElement(By.xpath("//*[@id=\"gh-ac\"]")).sendKeys("Mobile");
  Thread.sleep(1000);
  driver.findElement(By.xpath("//*[@id=\"gh-btn\"]")).sendKeys(Keys.RETURN);
  Thread.sleep(1000);
  
 }

@Test
public void test2() throws InterruptedException {

 //maximize the window 
 driver.manage().window().maximize();
 driver.get("https://www.ebay.com");
 Thread.sleep(1000);
 
 String actualTitle = driver.getTitle();
 Assert.assertEquals(actualTitle, expectedTitleebay);
 
 driver.findElement(By.xpath("//*[@id=\"gh-ac\"]")).sendKeys("Mobile");
 Thread.sleep(1000);
 driver.findElement(By.xpath("//*[@id=\"gh-btn\"]")).sendKeys(Keys.RETURN);
 Thread.sleep(1000);
 
}
 
 @AfterTest
 public void  tearDown() {
  driver.quit();
}
}
``` 

You will see that two browsers are opening **one after the another** , validate the title, input “Mobile” as the value and hit enter.

This TestNG class contain two *@Test* annotations and sites are running on one browser . In this case I have written the code to choose the browser in the *@BeforeTest* and if you want you can call it from another class. You can pass it from a parameter and change it.

So lets try to run the same thing using the **testing.xml** file by passing a parameter value to the class.

###Creating a testing.xml file

Go to your *test.java* class right click on it, go to *TestNG* section and click on the *convert to TestNG* option. You will see a window like this.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5uwydd5ttgxcmfm099yf.PNG)

AS you can see I have name my Suite name as *“Suite1”* and Test name as *“Test1”*

**Class selection:** Here we can select what level we want to create our XML document.(class or package)

**Parallel mode:** This will allow us to choose whether we want to run our tests in parallel mode(classes/methods/tests) or not.

**Thread count:** This will choose the thread count we want to run our tests.

For the moment lets create XML file in class level. You will see our **testing.xml** file like bellow.
```javascript
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite1">
  <test thread-count="5" name="Test1">
    <classes>
      <class name="test.test"/>
    </classes>
  </test> <!-- Test1 -->
</suite> <!-- Suite1 -->
```
You will see the browser is opening and do the actions accordingly. Now the case is what if we want to run the test in multiple browsers (both chrome and firefox) and parallelly.
###Demo Test Run

Before our test run change the **@BeforeTest** as follow because we are passing the **browserName** as a parameter from **testing.xml** file

```javascript
@Parameters("browserName")
@BeforeTest
public void setUp(String browserName){
if(browserName.equalsIgnoreCase("chrome")) {
  //initializing and starting the Chromebrowser
  WebDriverManager.chromedriver().setup();
  driver = new ChromeDriver();
 }else if(browserName.equalsIgnoreCase("firefox")) { 
  //initializing and starting the Chromebrowser  
  WebDriverManager.firefoxdriver().setup();   
  driver = new FirefoxDriver();  
 }
}
```
Also make sure you remove one *@Test* annotation because we can launch multiple number of browsers from the **testing.xml** file here after.

You just need to make a little change in the **testing.xml** file to run on multiple browsers and run the suite.

Inside the **Test** tag pass the browser parameter to the class by putting this code. In here I have passed chrome and firefox.

```javascript
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite1" parallel="tests" thread-count="2">
 
  <test name="test on firefox">
  <parameter name="browserName" value="firefox"></parameter>
    <classes>
      <class name="test.test"/>
    </classes>
  </test> <!-- Test1 -->
  
  <test name="test on chrome">
  <parameter name="browserName" value="chrome"></parameter>
    <classes>
      <class name="test.test"/>
    </classes>
  </test> <!-- Test1 -->
  
</suite> <!-- Suite1 -->
``` 

I have written two <test> tags for each browser mentioning its name. You will see two browsers are running parallelly.

So this is how we run multiple browsers parallelly using **testing.xml** file.
But if you noticed I have given a **thread count** as 2. What is meant by this?

###Thread count

It’s the number of tests that are run at the same time. It’s like saying how many cars in a fleet that you want on the highway at the same time. If you say you want them to take up three lanes, then they will take up no more than three lanes, but it will take longer to get all cars through. If you say five lanes, then they will take up no more than five lanes, but it will take less time to get all cars through.

So in here as I running this test only from two browsers I have mentioned thread count as 2. So lets see How it works. For better understanding I have put another firefox browser <test> tag in the **testing.xml file** to understand the thread count.
```javascript
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite1" parallel="tests" thread-count="2">
 
  <test name="test on firefox">
  <parameter name="browserName" value="firefox"></parameter>
    <classes>
      <class name="test.test"/>
    </classes>
  </test> <!-- Test1 -->
  
  <test name="test on chrome">
  <parameter name="browserName" value="chrome"></parameter>
    <classes>
      <class name="test.test"/>
    </classes>
  </test> <!-- Test1 -->
   
  <test name="test2 on firefox">
  <parameter name="browserName" value="firefox"></parameter>
    <classes>
      <class name="test.test"/>
    </classes>
  </test> <!-- Test1 -->
</suite> <!-- Suite1 -->
```

First put this code at the end of **test()* method and see the output in the console. This will show the current thread ID the test is running.
```javascript
System.out.println("This test is on: " + Thread.currentThread().getId());
``` 

In bellow results you will see two tests are running on two different threads.
First it runs on thread 15 at the same time thread 16 is used. In the third test it search for the available thread and use that. In this case thread 15 was free and launched the *test 2 on firefox.*
```javascript
This test is on: 15
This test is on: 16
This test is on: 15
``` 

So this is how we use thread count and maximize our efficiency. Its recommended to use higher thread count as it won’t make any unnecessary traffic in the memory.

In here I have only used one class but you can use multiple classes and also we can run our tests calling methods using <method> tag. You can <include> or <exclude> any given method.
```javascript
<class name="class_name" />
<method>
    <include name="MethodName"></include>
    <exclude name="MethodName"></include>
</method>
```

Here in this article we have used **testing.xml** file to run our TestNG tests parallelly in a selenium project. Also we used multiple browsers to run them parallelly.

For your reference find my GitHub project [here](https://github.com/mwickramanayaka/testing.xml-demo.git)

####𝑻𝑯𝑰𝑵𝑲 𝑸𝑼𝑨𝑳𝑰𝑻𝒀!