Groups in TestNG

โšก Smart Summary

Groups in TestNG let you tag test methods with logical labels, then include or exclude them through an XML suite. This approach simplifies smoke, regression, and dependency-driven runs without rewriting Java code.

  • ๐Ÿท๏ธ Annotation Syntax: Use @Test(groups = {"smoke","regression"}) to tag any method with one or more logical group names.
  • ๐Ÿ“œ XML Control: The <groups><run><include> and <exclude> tags inside testng.xml decide which tagged methods actually execute.
  • ๐Ÿ”— Dependencies: The dependsOnGroups attribute forces ordering so prerequisite groups always finish before dependent tests start.
  • ๐Ÿค– AI Selection: AI test-impact tools map code changes to relevant groups, so only affected suites run on each commit.
  • ๐Ÿงช TestNG 7.x: Modern releases keep groups fully compatible with parallel execution, listeners, and Maven Surefire pipelines.

Groups in TestNG

TestNG is a testing framework that covers unit, functional, end-to-end, UI, and integration tests for Java projects.

You can run a single package or many packages (a package encapsulates related classes in a defined directory layout) by creating an XML suite and triggering it through Maven.

TestNG Groups with Example

You use groups in TestNG when:

  • You do not want to scatter test methods across many classes purely by functional area, and
  • You want to skip (not execute) selected test cases as if they were absent from the codebase.
  • To achieve both goals, you tag methods into logical groups. TestNG then honors the “include” and “exclude” filters declared in the XML suite.

The snippet below shows the group-tagging syntax used on a test method.

@Test (groups = { “bonding”, “strong_ties” })

Two group names are used here, namely bonding and strong_ties. These are logical labels that you can rename to suit your project.

The <groups> tag marks the start of group filters inside the XML suite.

You then customize the XML to pick a chosen group from the tagged classes. The example below shows the group declaration syntax.

<groups>
<run>
<include name=“bonding” />
</run>
</groups>

Assume a single class contains 10 test methods.

Out of those methods:

  • 6 methods carry the bonding group, and
  • 4 methods carry the strong_ties group.

Next, you set up the Maven and Java paths and use the Eclipse IDE to demonstrate group usage through XML files inside a Java-based Maven project.

Create XML for TestNG with Tags

  • The XML (Extensible Markup Language) file in the Maven framework stores the configuration for one or more tests, declared inside the <suite> tag.
  • Each test entry is wrapped in a <test> tag and can hold one or more TestNG classes.
  • A Java class with one or more @Test annotations on its methods is treated as a TestNG class.

Multiple tags appear in sequence to build a working testng.xml file, namely <suite>, <test>, and <class>.

  • The <suite> tag holds the suite-level name used in TestNG reports for execution summaries.
  • The <test name=”Guru 99 Smoke Test Demo”> tag holds a logical test name; the report uses it for pass, fail, and skip counts plus total execution time and group metadata.
  • The <class name=”com.group.guru99.TC_Class1″ /> tag points to the test class, where com.group.guru99 is the package and TC_Class1 is the class name.
<?xml version=”1.0″ encoding=”UTF-8″ ?>
<!DOCTYPE suite SYSTEM “http://testng.org/testng-1.0.dtd”>
<suite name=“Suite”>
<test name=“Guru 99 Smoke Test Demo”>
<groups>
<run>
<include name=“strong_ties” />
</run>
</groups>
<classes>
<class name=“com.group.guru99.TC_Class1” />
</classes>
</test>
</suite>

This XML configuration is referenced in the video walkthroughs in the next sections.

“exclude” or “include” in test XML

If the group mechanism feels heavy for a small filter, the testng.xml suite also lets you exclude or include individual test methods by name.

Exclude Tag: Syntax for exclude tag <exclude name=“${TEST_CASE_NAME}” />
Include Tag: Syntax for include tag <include name=“${TEST_CASE_NAME}” />

Note: You can include or exclude many test cases in a single run, and the same syntax applies to group filters.

Using dependsOnGroups for Ordered Execution

Beyond plain inclusion, TestNG lets one group depend on another using the dependsOnGroups attribute. The runner ensures every method in the parent group finishes before any dependent method starts, which keeps preconditions reliable.

  • Login first, then transactions: Tag login methods with group = "auth", and tag transfer tests with dependsOnGroups = {"auth"}. The transfer tests run only after login passes.
  • Skip on failure: If a method in the parent group fails, TestNG marks the dependent methods as skipped instead of failing them outright, which keeps reports honest.
  • Combine with alwaysRun: Cleanup methods should set alwaysRun = true so teardown still runs even when an upstream group fails.

This pattern is common for end-to-end suites where API setup must complete before UI assertions kick off.

Run TestNG Group, include, exclude code (video demo)

Below is a walkthrough of the Java code and the XML suite that drive the group, exclude, and include behavior.

Test Scenario: Launch the Guru99 demo banking site, verify a few elements on the login page, enter credentials, and re-verify a few items on the dashboard after login.

Run TestNG Group, Include, Exclude Code

Note: Each step lives in its own method, but at runtime the order depends on the entries in the XML suite.

  • Method 1: Initialize the browser and launch the URL (tc01LaunchURL()).
  • Method 2: Verify the login page heading (tc02VerifyLaunchPage()).
  • Method 3: Enter user name and password on the login form (tc03EnterCredentials()).
  • Method 4: Verify the presence of the Manager ID on the user dashboard (tc04VerifyLoggedInPage()).
  • Method 5: Verify additional links on the user dashboard (tc05VerifyHyperlinks()).

Code for the scenario:

package com.group.guru99;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.Test;

public class TC_Class1 {
public static final WebDriver webDriver = new FirefoxDriver();

String launchPageHeading = “//h3[text()=’Guru99 Bank’]”;
final String userName_element = “//input[@name=’uid’]”, password_element = “//input[@name=’password’]”,
signIn_element = “//input[@name=’btnLogin’]”;
final String userName_value = “mngr28642”, password_value = “ydAnate”;
final String managerID = “//td[contains(text(),’Manger Id’)]”;
final String newCustomer = “//a[@href=’addcustomerpage.php’]”, fundTransfer = “//a[@href=’FundTransInput.php’]”;

/** This test case initializes the webDriver */
@Test(groups = { “bonding”, “strong_ties” })
public void tc01LaunchURL() {
webDriver.manage().window().maximize();
webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
webDriver.get(“https://www.demo.guru99.com/V4/”);
}

/** Checks the presence of the heading on the login page */
@Test(groups = { “bonding” })
public void tc02VerifyLaunchPage() {
Assert.assertTrue(webDriver.findElement(By.xpath(launchPageHeading)).isDisplayed(),
“Home Page heading is not displayed”);
System.out.println(“Home Page heading is displayed”);
}

/** Enters user name, password, then clicks signIn */
@Test(groups = { “bonding”, “strong_ties” })
public void tc03EnterCredentials() {
webDriver.findElement(By.xpath(userName_element)).sendKeys(userName_value);
webDriver.findElement(By.xpath(password_element)).sendKeys(password_value);
webDriver.findElement(By.xpath(signIn_element)).click();
}

/** Verifies the manager ID on the dashboard */
@Test(groups = { “strong_ties” })
public void tc04VerifyLoggedInPage() {
Assert.assertTrue(webDriver.findElement(By.xpath(managerID)).isDisplayed(),
“Manager ID label is not displayed”);
System.out.println(“Manger Id label is displayed”);
}

/** Checks New customer link and FundTransfer link on the dashboard */
@Test(groups = { “bonding” })
public void tc05VerifyHyperlinks() {
Assert.assertTrue(webDriver.findElement(By.xpath(newCustomer)).isEnabled(),
“New customer hyperlink is not displayed”);
System.out.println(“New customer hyperlink is displayed”);

Assert.assertTrue(webDriver.findElement(By.xpath(fundTransfer)).isEnabled(),
“Fund Transfer hyperlink is not displayed”);
System.out.println(“Fund Transfer hyperlink is displayed”);
}
}

Please note: the demo banking credentials remain valid for roughly 20 days, so a local run may show an invalid-credentials error after that window expires.

Explanation of the code:

Five test methods, one per action, each carry a groups attribute on the @Test annotation.

The two logical group labels are strong_ties and bonding.

  • The first and third methods carry both bonding and strong_ties, so they run whenever either group is included in the suite. This is a common pattern for shared test case steps.
  • The second method is tagged only with bonding, so it runs only when the bonding group is included.
  • The fourth method is tagged only with strong_ties, so it runs only when that group is included.
  • The fifth method is tagged only with bonding, so it runs only when the bonding group is included.

Four execution scenarios follow:

Scenario 1: Run every test method regardless of group. Remove the <groups> block from the running XML.

Scenario 2: Run only methods tied to a chosen group, namely strong_ties or bonding. Please refer to the video below.

  • In the first part of the video, the <groups> block is commented out, so every test method runs.
  • In the second part, the group filter is restored, and only the matching methods run.

Scenario 3: Apply the exclude filter to skip selected test cases. Please refer to the video.

  • The demo excludes tc02 by name in the running XML, and the result report confirms that the excluded method does not run.

Scenario 4: Apply the include filter to run only tc01LaunchURL, tc03EnterCredentials, and tc05VerifyHyperlinks. Please refer to the video.

In this run, only the methods listed in the include filter execute, exactly as configured.

Download the sample project from the link below.

Download the above Code

Conclusion

Groups in TestNG bring structure to large Selenium and unit suites by replacing one-off class splits with declarative XML filters.

Tag your methods with @Test(groups = {...}), then use <include>, <exclude>, and dependsOnGroups to drive smoke, regression, and end-to-end runs from the same Maven project on TestNG 7.x.

FAQs

A group is a logical label attached to a test method through the groups attribute on @Test. The XML suite then picks groups using include and exclude filters, so you decide at runtime which tagged methods execute.

Inside <groups><run>, the <include name="..."> tag whitelists groups for the run, and <exclude name="..."> blocks them. TestNG applies excludes after includes, so an excluded group is always skipped, even when also listed in include.

The dependsOnGroups attribute on @Test forces TestNG to run every method in the listed group before the dependent method starts. If any prerequisite method fails, TestNG marks the dependent method as skipped rather than failed.

Yes. The groups attribute accepts an array, so @Test(groups = {"smoke", "regression"}) places one method in both groups. TestNG runs that method whenever either group is included in the suite, which keeps shared steps DRY.

TestNG 7.x is the maintained line, with releases under the org.testng:testng Maven coordinate. It keeps groups, parallel execution, and listeners fully compatible with modern Selenium 4 and JDK 17 projects.

AI test-impact tools analyze code diffs, then map changed classes to the groups that cover them. The pipeline runs only those tagged groups on each pull request, cutting feedback time while keeping risky paths under test.

Yes. AI clustering algorithms read historical failure logs, flag flaky tests, and propose a stable subset tagged as regression. Engineers approve the list, then TestNG runs that group nightly, which keeps the suite tight without losing coverage.

Summarize this post with: