The Ultimate Guide to TestNG Groups
What are TestNG Groups?
TestNG Groups allow a way to group multiple test cases written in Selenium to be grouped under a common name. Using groups in TestNG you can run multiple test cases which are tagged using a group name together, thereby separating the test cases as per their tagged groups.
Consider a scenario, where there are multiple test cases in a test suite. These test cases are a part of different test types like unit test, smoke test, regression test, sanity test, etc. Now, if you need to maintain your Selenium test cases, you can use TestNG groups using which you can segregate these test cases using groups for these test methods. This way you would not need to maintain multiple test suites for the different tests.
Now, we know that TestNG groups can help us maintain our tests as per the different test categories, let us see the advantages offered by using TestNG Groups.
Advantages Of TestNG Groups
Selective Test Executions
TestNG Groups allows execution of specific test clusters. This can be very beneficial when you need to test your application against the different quality parameters like functionality, or security. You can cherry pick your tests using groups and see the behavior of the application.
Streamlined Test Suite Management
Automation test suites are bound to expand. It can be very challenging to maintain the tests individually with this growth. TestNG Groups provide ease in maintenance of these tests in a systematic manner.
Parallel Test Execution
Tests that are tagged within the same group in TestNG can be executed in parallel. Using these capabilities you can marginally bring down the execution time for your tests, thereby increasing efficiency.
Adaptability and Customization
Using TestNG groups you can have the flexibility to design and manage your tests as per the need of your project. This capability allows you to ensure that your test strategy is well aligned to the demands of your project.
How to group test cases in TestNG?
To specify groups in TestNG, you need to use the “group” attribute with the @TestNG Annotations. Additionally, you need to specify groups in the testng.xml under the <suite> or <test> tag. We will now walk through the steps you will need to follow to group your test cases in testNG.
Step 1: Annotating the test methods
To begin with the steps of using TestNG Groups, you will have to group the test cases as per their type. Parameter groups is passed to the @Test annotation which specifies which group the test belongs to. The syntax to do so is as follows:
@Test(groups ="group_name")
public void testMethod() {
//Test code here
}
You also have the flexibility to assign a test method to multiple test groups. An example for the same is:
@Test(groups ={"smoke", "regression"})
public void testLogin() {
//Test code here
}
In the above code, the testLogin() method will be a part of both the groups viz, smoke and regression.
In the above code, the testLogin() method will be a part of both the groups viz, smoke and regression.
Step 2: Specifying the test groups in testng xml
You can define the test groups in the testNG XML configuration. You can flexibly include or exclude the test groups you would like to execute during a test run. To do so, you need to configure the <groups> tag within the <test>. The syntax to do so is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Test">
<groups>
<run>
<include name="smoke"> </include>
</run>
</groups>
<classes>
<class name="testngGroups.groups.groupTests"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
In the above example, all the test methods that are grouped as smoke will be executed when you try to run the testng suite. If you need to exclude a particular group in an execution you can define it within the <exclude> tag as shown below:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Test">
<groups>
<run>
<include name="smoke"> </include>
<exclude name="regression"> </exclude>
</run>
</groups>
<classes>
<class name="testngGroups.groups.groupTests"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Step 3: Executing the TestNG tests with the group configuration
After setting up the code as well as the xml configuration file, you can simply execute your tests either through an IDE, or through command line, or even the build tools like Maven. Upon execution you will see that the groups you specified in the <include> tag would have executed and if there was any group within the <exclude> that it would not have been executed.
Now that we know the steps to implement TestNG Groups, we will see the demonstrations corresponding to different scenarios we might want to execute using them.
Demonstrations(Testng Groups Example)
Running Test Cases Of Same Group
We will now create a test class where we will be creating two test methods and assign them to a group named url. Let us look at the Selenium Java code for the same:
package pomBatchOne.tests;
import org.testng.annotations.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class urlTest {
WebDriver driver;
@Test(groups="url")
public void testgrid() {
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://testgrid.io/");
System.out.println(driver.getTitle());
driver.quit();
}
@Test(groups="url")
public void google() {
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.google.com");
System.out.println(driver.getTitle());
driver.quit();
}
}
As you can see, groups have been assigned to the two tests. Let us have a look at the testng xml now-
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Test">
<groups>
<run>
<include name="url"></include>
</run>
</groups>
<classes>
<class name="pomBatchOne.tests.urlTest"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Since we need to include the group “url” for execution, we have written it to be included within the test tag as can be seen from the xml above. Let us now execute the testng xml and see the result-
As can be seen from the above snapshot, the execution was successful and our test was executed where the group “url” was included while execution.
Next, we will see a demonstration to execute tests that are within multiple groups.
Running Test Cases Of Multiple Groups
We just saw how to write and execute the test methods that are a part of a group. There may be scenarios where a test method might be a part of multiple groups. Additionally, you might want to execute your tests so that the test methods belonging to smoke and regression tests are executed in one go. For example you might want to execute a login test case in the smoke as well as a regression test suite. TestNG groups provide you the flexibility to assign a test case to multiple groups as per the project requirements. Along with that you may include multiple groups to be executed through testng xml.
Below code shows example for different test methods corresponding to different groups-
package pomBatchOne.tests;
import org.testng.annotations.Test;
import org.testng.annotations.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class urlTest {
WebDriver driver;
@Test(groups="url")
public void testgrid() {
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://testgrid.io/");
System.out.println(driver.getTitle());
driver.quit();
}
@Test(groups="url")
public void google() {
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.google.com");
System.out.println(driver.getTitle());
driver.quit();
}
@Test(groups="search")
public void googleSearchOne() {
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.google.com");
driver.findElement(By.name("q")).sendKeys("testng groups in selenium");
driver.findElement(By.name("btnK")).click();
System.out.println(driver.getTitle());
driver.quit();
}
@Test(groups="search")
public void googleSearchTwo() {
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.google.com");
driver.findElement(By.name("q")).sendKeys("testgrid features and benefits");
driver.findElement(By.name("btnK")).click();
System.out.println(driver.getTitle());
driver.quit();
}
@Test(groups= {"url","search"})
public void groupMethod() {
System.out.println("This is a sample method that is part of both url and search group...");
}
}
The testng.xml that includes both the groups for execution will look like below-
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Test">
<groups>
<run>
<include name="url"></include>
<include name="search"></include>
</run>
</groups>
<classes>
<class name="pomBatchOne.tests.urlTest"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Upon executing the xml you will see execution results like below-
Groups of Groups in TestNG
In TestNG, groups can be included in other groups. This type of group set up is called “MetaGroups”. Using these MetaGroups you can create a collection of tests such that you can execute tests tagged within different groups as a single test. In the below example, we are tagging the different test methods as “url1”, “url2”, “search1” and “search2” respectively.
package pomBatchOne.tests;
import org.testng.annotations.Test;
import org.testng.annotations.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class urlTest {
WebDriver driver;
@Test(groups="url1")
public void testgrid() {
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://testgrid.io/");
System.out.println(driver.getTitle());
driver.quit();
}
@Test(groups="url2")
public void google() {
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.google.com");
System.out.println(driver.getTitle());
driver.quit();
}
@Test(groups="search1")
public void googleSearchOne() {
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.google.com");
driver.findElement(By.name("q")).sendKeys("testng groups in selenium");
driver.findElement(By.name("btnK")).click();
System.out.println(driver.getTitle());
driver.quit();
}
@Test(groups="search2")
public void googleSearchTwo() {
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.google.com");
driver.findElement(By.name("q")).sendKeys("testgrid features and benefits");
driver.findElement(By.name("btnK")).click();
System.out.println(driver.getTitle());
driver.quit();
}
}
Now, in the testng.xml, we define two new group names, i.e, “urlGroup” and “searchGroup” which would include the individual groups as shown below-
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Test">
<groups>
<define name="urlGroup">
<include name="url1"></include>
<include name="url2"></include>
</define>
<define name="searchGroup">
<include name="search1"></include>
<include name="search2"></include>
</define>
<run>
<include name="urlGroup"></include>
<include name="searchGroup"></include>
</run>
</groups>
<classes>
<class name="pomBatchOne.tests.urlTest"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
As you can see, we can include these groups of group directly to execute. Additionally you may create a super group including all the groups you would want to run in an execution if you make a few changes in the xml like below-
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Test">
<groups>
<define name="urlGroup">
<include name="url1"></include>
<include name="url2"></include>
</define>
<define name="searchGroup">
<include name="search1"></include>
<include name="search2"></include>
</define>
<define name="superGroup">
<include name="urlGroup"></include>
<include name="searchGroup"></include>
</define>
<run>
<include name="superGroup"></include>
</run>
</groups>
<classes>
<class name="pomBatchOne.tests.urlTest"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
When you execute the above testng suite, you will see that all the groups that have been defined under superGroup would be executed-
Include and Exclude Groups in TestNG
As you have already seen that we can include the groups we want to execute in our test. In a similar way you may explicitly exclude a specific group from execution. Let us take a simple example, where we will be creating multiple test methods with different groups and a couple of test methods which have multiple groups.
package pomBatchOne.tests;
import org.testng.annotations.Test;
public class IncExc {
@Test(groups="gpOne")
public void testOne() {
System.out.println("The test belongs to Group One");
}
@Test(groups="gpTwo")
public void testTwo() {
System.out.println("The test belongs to Group Two");
}
@Test(groups="gpOne")
public void testThree() {
System.out.println("The test belongs to Group One");
}
@Test(groups="gpTwo")
public void testFour() {
System.out.println("The test belongs to Group Two");
}
@Test(groups={"gpOne","gpTwo"})
public void testFive() {
System.out.println("The test belongs to Group One as well as Group Two");
}
}
As you can see from the code above, we have created five test methods. Of these two belong to “gpOne” only, two belong to “gpTwo” only and one belong to both “gpOne” and “gpTwo”. We will now create testng.xml for the class, so that we include “gpOne” in execution and exclude”gpTwo” in execution and then see the result.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Test">
<groups>
<run>
<include name="gpOne"></include>
<exclude name="gpTwo"></exclude>
</run>
</groups>
<classes>
<class name="pomBatchOne.tests.IncExc"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Upon execution, we see that only the test methods that belong to “gpOne” are executed. No test method that has the tag of “gpTwo” is executed. This means that even the test method that was a part of multiple groups, viz “gpOne” and “gpTwo” is also not executed. The results from console are as below-
Using Regular Expressions in TestNG Groups
You can use regular expressions like “.*” which implies anything that matches the given pattern, in testng xml for executing specific groups. Note that you should not confuse regular expressions with Wildmats, i.e “*” while using TestNG. We will take the example of below code where there are multiple test methods tagged with groups like: “gpOne”,”gpTwo” and ”GroupOne”.
package pomBatchOne.tests;
import org.testng.annotations.Test;
public class RegularExp {
@Test(groups="gpOne")
public void testOne() {
System.out.println("The test belongs to Gp One");
}
@Test(groups="gpTwo")
public void testTwo() {
System.out.println("The test belongs to Gp Two");
}
@Test(groups="gpOne")
public void testThree() {
System.out.println("The test belongs to Gp One");
}
@Test(groups="gpTwo")
public void testFour() {
System.out.println("The test belongs to Gp Two");
}
@Test(groups={"gpOne","gpTwo"})
public void testFive() {
System.out.println("The test belongs to Gp One as well as Gp Two");
}
@Test(groups="GroupOne")
public void testSix() {
System.out.println("The test belongs to Group One");
}
}
We will not create the testng.xml to include the execution of tests that begin with “gp” in their name. For doing so we will use regular expressions.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Test">
<groups>
<run>
<include name="gp.*"></include>
</run>
</groups>
<classes>
<class name="pomBatchOne.tests.IncExc"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Upon executing the above xml, you will see the results where five test methods will be executed and only one method which is from the “GroupOne” will not be executed.
Conclusion
And with this, we wrap up the understanding of using TestNG Groups in our test executions. We now know how beneficial and efficient using TestNG Groups is when we want to maintain our test suite as per the testing needs. By identifying groups for the test methods it becomes easier to execute tests corresponding to a specific type. Additionally you may leverage the use of parallel execution to achieve quick results. Just by simply, using groups as a parameter in the @Test annotation you can make use of this feature by including or excluding the group from the testng xml. Additionally, you may create flexible test scripts by using single or multiple or even combinations of groups for your test methods. You can group these groups for better efficiency of execution and also use regular expressions to simplify using groups with similar names
Source: This article was originally published at https://testgrid.io/blog/testng-groups/
Subscribe to my newsletter
Read articles from Ronika Kashyap directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Ronika Kashyap
Ronika Kashyap
Experienced Software Tester with 7+ years of ensuring product excellence. Proficient in automation, API testing, and Agile. Achieved 30% test coverage increase. Dedicated to delivering top-notch software.