Parallel Testing using TestNG and Selenium

What is Parallel Testing, and why is it important?

Parallel testing is a software testing technique where multiple test cases are executed simultaneously to expedite the testing process. In the context of TestNG, a testing framework for Java, parallel testing allows the concurrent execution of test methods, classes, or suites. This is crucial for accelerating the testing cycle, especially in large-scale applications where numerous test cases need to be executed.

Advantages vs Disadvantages

Advantages of Parallel TestingDisadvantages of Parallel Testing
Time Efficiency: Accelerates test execution, reducing overall testing time.Increased Complexity: Introduces complexity in test design and maintenance.
Resource Optimization: Efficiently utilizes available hardware and minimizes resource bottlenecks.Resource Overhead: Requires additional setup and maintenance of parallel test environments.
Early Detection of Defects: Facilitates early identification of defects through concurrent test execution.Debugging Challenges: Poses challenges in pinpointing the root cause of concurrent test failures.

Where can we apply Parallel Test Execution in TestNG?

Parallel test execution in TestNG can be applied at various levels:

  1. Test Methods: Execute individual test methods in parallel.

  2. Test Classes: Run multiple test classes in parallel.

  3. Test Suites: Execute entire test suites concurrently.

What are Threads in TestNG?

In TestNG, the concept of threads is integral to parallel test execution. Each thread represents an independent test instance, allowing multiple tests to run simultaneously.

Performance Comparison between Serialized and Parallelized Test Execution in TestNG

Conducting a performance comparison between serialized and parallelized test execution involves measuring factors such as total execution time, resource utilization, and overall system efficiency.

Real-time Example:

A suite of 500 test cases is executed sequentially, taking 5 hours. The same suite, when executed in parallel with a thread count of 5, completes in 1 hour. This showcases a significant performance improvement achieved through parallel testing.

Example for Running Test Parallelly in TestNG using Selenium

// ChromeTestClass.java
package com.mystore.testcases;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import io.github.bonigarcia.wdm.WebDriverManager;

public class ChromeTestClass {

    private static ThreadLocal<WebDriver> chromeDriver = new ThreadLocal<>();

    @BeforeMethod
    public void setUp() {
        // Set up ChromeDriver using WebDriverManager
        WebDriverManager.chromedriver().setup();
        chromeDriver.set(new ChromeDriver());
    }

    @Test
    public void goToAmazon() {
        chromeDriver.get().get("https://www.amazon.com");
        chromeDriver.get().manage().window().maximize();
        // Additional test steps
    }

    @Test
    public void goToFacebook() {
        chromeDriver.get().get("https://www.facebook.com");
        chromeDriver.get().manage().window().maximize();
        // Additional test steps
    }

    @Test
    public void openInstagram() {
      chromeDriver.get().get("https://www.instagram.com");
      chromeDriver.get().manage().window().maximize();
        // Additional test steps
    }

    @Test
    public void openTwitter() {
      chromeDriver.get().get("https://www.twitter.com");
      chromeDriver.get().manage().window().maximize();
        // Additional test steps
    }
}
// FirefoxTestClass.java
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class FirefoxTestClass {

    private static ThreadLocal<WebDriver> firefoxDriver = new ThreadLocal<>();

    @BeforeClass
    public void setUp() {
        // Set up FirefoxDriver
        System.setProperty("webdriver.gecko.driver", "path/to/geckodriver");
        firefoxDriver.set(new FirefoxDriver());
    }

    @Test
    public void openInstagram() {
        firefoxDriver.get().get("https://www.instagram.com");
        // Additional test steps
    }

    @Test
    public void openTwitter() {
        firefoxDriver.get().get("https://www.twitter.com");
        // Additional test steps
    }

    @AfterClass
    public void tearDown() {
        // Close FirefoxDriver
        if (firefoxDriver.get() != null) {
            firefoxDriver.get().quit();
        }
    }
}
package com.mystore.testcases;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class IETestClass {

    private ThreadLocal<WebDriver> ieDriver = new ThreadLocal<>();

    @BeforeMethod
    public void setUp() {
        // Set up InternetExplorerDriver using WebDriverManager
        WebDriverManager.iedriver().setup();
        ieDriver.set(new InternetExplorerDriver());
    }

    @Test
    public void openMicrosoft() {
        ieDriver.get().get("https://www.microsoft.com");
        // Additional test steps
    }

    @Test
    public void openLinkedIn() {
        ieDriver.get().get("https://www.linkedin.com");
        // Additional test steps
    }

}

TestNG XML Configurations

1.Running Test Methods in Parallel

<!-- testng_method_parallel.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="ParallelClassSuite" parallel="methods" thread-count="5">
    <test name="TestMethod">
        <classes>
            <class name="com.mystore.testcases.ChromeTestClass"/>
        </classes>
    </test>
</suite>

It specifies that the methods within the test classes will run in parallel.

2.Running Test Classes in Parallel

<!-- testng_class_parallel.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="ParallelClassSuite" parallel="classes" thread-count="5">
    <test name="TestMethod">
        <classes>
            <class name="com.mystore.testcases.ChromeTestClass"/>
            <class name="com.mystore.testcases.FirefoxTestClass"/>
        </classes>
    </test>
</suite>

It specifies that the test classes will run in parallel, meaning one method from each class will run parallel based on the thread count specified.

3.Running Test Suites in Parallel

<!-- testng_suite_parallel.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="ParallelClassSuite" parallel="tests" thread-count="2">
    <test name="Test1">
        <classes>
            <class name="com.mystore.testcases.ChromeTestClass"/>
            <class name="com.mystore.testcases.FirefoxTestClass"/>
        </classes>
    </test>
    <test name="Test2">
        <classes>
            <class name="com.mystore.testcases.IETestClass"/>
        </classes>
    </test>
</suite>

It specifies that the entire tests will run in parallel meaning one thread will be allotted to "Test1" and another to "Test2 based on the thread count.

Conclusion

Parallel testing in TestNG offers a powerful mechanism to enhance the efficiency of the testing process. By strategically distributing test execution, teams can achieve faster feedback, optimize resource utilization, and identify defects early in the development lifecycle. While it comes with its set of challenges, the benefits of parallel testing outweigh the drawbacks, making it an indispensable practice in modern software testing.