100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Testing

Selenium with TestNG

Learn how TestNG's annotations, grouping, and reporting turn raw Selenium WebDriver scripts into a structured, parallelizable, CI-ready test suite.

Test Framework IntegrationIntermediate9 min readJul 10, 2026
Analogies

Selenium with TestNG

TestNG is a Java testing framework, inspired by JUnit but designed for broader test configuration needs, that pairs naturally with Selenium WebDriver to structure, sequence, and report browser automation suites. Where raw Selenium only drives a browser, TestNG supplies annotations for setup and teardown, XML-driven suite configuration, grouping, and built-in HTML reports, turning a pile of WebDriver scripts into an organized, repeatable regression suite.

🏏

Cricket analogy: Just as a cricket team needs a fixed batting order and designated roles (opener, finisher, death bowler) rather than eleven players improvising, TestNG imposes a defined lifecycle and structure on what would otherwise be ad-hoc Selenium scripts.

TestNG Annotations and the Test Lifecycle

TestNG exposes a rich set of lifecycle annotations: @BeforeSuite and @AfterSuite run once per suite, @BeforeClass/@AfterClass once per class, @BeforeMethod/@AfterMethod before and after every @Test method, and @BeforeTest/@AfterTest around the <test> tag in testng.xml. In a Selenium context this maps cleanly onto browser lifecycle management — @BeforeMethod typically instantiates a fresh WebDriver and navigates to the base URL, while @AfterMethod calls driver.quit() to close the browser and release resources, guaranteeing test isolation even if a prior test failed.

🏏

Cricket analogy: The toss, the innings break, and the post-match presentation happen at fixed points regardless of how the middle overs play out, just as @BeforeMethod and @AfterMethod bracket every @Test method regardless of what happens inside it.

Grouping, Prioritization, and Parallel Execution

TestNG lets you tag tests with groups (e.g., groups = {"smoke", "regression"}) so testng.xml can select a subset to run, order execution deterministically with priority or dependsOnMethods/dependsOnGroups, and run classes or methods in parallel via the parallel attribute (methods, classes, or tests) combined with thread-count. For Selenium suites this is what makes a 500-test regression pack run in minutes instead of hours by spreading independent browser sessions across threads, while still guaranteeing that, say, a login test runs before tests that depend on being logged in.

🏏

Cricket analogy: A T20 franchise picks an XI suited to the format (aggressive openers for powerplay) the way TestNG groups let you pick a 'smoke' XI of tests, while overs bowled in parallel by different bowlers across matches mirrors parallel thread execution.

java
// LoginTest.java
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.By;
import org.testng.Assert;
import org.testng.annotations.*;

public class LoginTest {
    private WebDriver driver;

    @BeforeMethod
    public void setUp() {
        driver = new ChromeDriver();
        driver.get("https://example.com/login");
    }

    @Test(groups = {"smoke", "regression"}, priority = 1)
    public void loginWithValidCredentials() {
        driver.findElement(By.id("username")).sendKeys("qa_user");
        driver.findElement(By.id("password")).sendKeys("Secr3t!");
        driver.findElement(By.id("loginBtn")).click();
        String header = driver.findElement(By.cssSelector("h1.welcome")).getText();
        Assert.assertEquals(header, "Welcome, qa_user");
    }

    @Test(groups = {"regression"}, dependsOnMethods = "loginWithValidCredentials")
    public void logoutClearsSession() {
        driver.findElement(By.id("logoutBtn")).click();
        Assert.assertTrue(driver.findElement(By.id("loginBtn")).isDisplayed());
    }

    @AfterMethod
    public void tearDown() {
        if (driver != null) driver.quit();
    }
}

<!-- testng.xml -->
<suite name="RegressionSuite" parallel="methods" thread-count="4">
  <test name="LoginFlow">
    <groups>
      <run>
        <include name="smoke"/>
      </run>
    </groups>
    <classes>
      <class name="LoginTest"/>
    </classes>
  </test>
</suite>

The testng.xml suite file is the single source of truth for which groups, classes, and parallel mode a given run uses — CI pipelines typically maintain separate XML files (smoke.xml, regression.xml, nightly.xml) pointing at the same test classes but selecting different groups, so you never need to change Java code to change what a pipeline stage runs.

TestNG Reporting and Listeners

TestNG automatically emits an emailable-report.html and an XML report (testng-results.xml) after every run, summarizing pass/fail/skip counts per method, and these integrate directly with CI tools like Jenkins, which can parse the XML for trend graphs. Beyond the default output, implementing ITestListener or IReporter interfaces lets you hook into events like onTestFailure to capture a Selenium screenshot at the moment of failure, or onTestSuccess to log timing — a pattern most real-world Selenium-TestNG frameworks use to attach failure screenshots automatically to reports like Extent Reports or Allure.

🏏

Cricket analogy: A scorecard published after a match shows every batsman's runs and every bowler's figures automatically; TestNG's emailable-report.html is that auto-generated scorecard for your test suite, with a listener acting like a broadcaster cutting to a replay the instant a wicket (failure) falls.

  • TestNG supplies lifecycle annotations (@BeforeSuite, @BeforeClass, @BeforeMethod, @Test, @AfterMethod, @AfterClass, @AfterSuite) that structure Selenium browser setup and teardown.
  • @BeforeMethod/@AfterMethod are the most common pairing for Selenium: instantiate WebDriver before each test, call driver.quit() after, guaranteeing isolation.
  • Groups (groups = {...}) let testng.xml select subsets of tests (smoke vs regression) without changing Java code.
  • priority and dependsOnMethods/dependsOnGroups control execution order and gate dependent tests.
  • parallel="methods|classes|tests" with thread-count drastically cuts suite runtime by running independent Selenium sessions concurrently.
  • testng.xml is the configuration file that ties classes, groups, and parallel mode together for a given CI run.
  • ITestListener/IReporter hooks (onTestFailure, etc.) are the standard way to auto-capture Selenium screenshots and feed rich reports like Extent or Allure.

Practice what you learned

Was this page helpful?

Topics covered

#Testing#SeleniumStudyNotes#TestingQA#SeleniumWithTestNG#Selenium#TestNG#Annotations#Test#StudyNotes#SkillVeris