One of the key features of TestNG is its ability to categorize test methods into groups. Groups in TestNG help you organize your tests into different categories, allowing you to execute them selectively based on the group they belong to. This article will dive deep into TestNG groups, explaining their significance and how to use them with examples.
- What are TestNG groups?
- How to assign a test case to a group
- How to run selected group(s)
- How to exclude a specific group
- QnAs on including and excluding groups
- Group of groups (Meta groups)
- Using regular expression with groups
- Grouping at the class level
Note: We have also attached a video at the end of this article. In case you are more comfortable with the video version, then please feel free to have a look
Let’s see the above points one by one.
What are TestNG groups?
In TestNG, a group is a way to categorize test methods, allowing us to organize and execute them selectively based on their grouping. By assigning test methods to one or more groups, you can manage and run related tests together, making it easier to handle large and complex test suites.
Regardless of whether test cases originate from different classes or packages, we can group them together and execute them as a single batch. For example, imagine a class that contains hundreds of test cases, some belonging to the “regression” group and others to the “sanity” group. Using TestNG, we can run only the “regression” or “sanity” group as needed rather than executing the entire set of test cases each time.
How to assign a test case to a group?
@Test annotation provides a “groups” attribute, where we can mention the name of the groups that the test belongs to.
Syntax of assigning group
@Test(groups = { "groupName1","groupName2" })
Let’s create a CodekruTest class where a test case belongs to “group1“, “group2” or “group3“.
public class CodekruTest {
@Test(groups = { "group1" })
public void test1() {
System.out.println("Executing test1 in CodekruTest class");
Assert.assertTrue(true);
}
@Test(groups = { "group2" })
public void test2() {
System.out.println("Executing test2 in CodekruTest class");
Assert.assertTrue(true);
}
@Test(groups = { "group1" })
public void test3() {
System.out.println("Executing test3 in CodekruTest class");
Assert.assertTrue(true);
}
@Test(groups = { "group3" })
public void test4() {
System.out.println("Executing test4 in CodekruTest class");
Assert.assertTrue(true);
}
}
Now, as we have assigned groups to test cases, let’s see how we can execute only a specific group.
How to run selected group(s)
We can use the <groups> tag in the testng.xml file to run a specific group. Please find below the syntax used to run a specific group.
<groups>
<run>
<include name="group1" />
</run>
</groups>
Using the syntax provided above, we can execute the test cases of the CodekruTest class that are part of “group1.”
<suite name="codekru">
<test name="codekruTest">
<groups>
<run>
<include name="group1" />
</run>
</groups>
<classes>
<class name="Test.CodekruTest">
</class>
</classes>
</test>
</suite>
Output after running the XML file –
Executing test1 in CodekruTest class
Executing test3 in CodekruTest class
We can see that only test1 and test3 were executed. This is how easily we can run a specific group in TestNG.
Note: The <groups>
tag does not need to be positioned specifically within the <test>
tag; it can be placed anywhere inside the <suite>
tag. The XML file shown below would still execute the test cases in “group1.”
The difference lies in the scope of the grouping. When the <groups>
tag is placed inside the <suite>
tag, the grouping applies to all test cases within the suite. And, if it is placed inside the <test>
tag, the grouping is limited to the test cases within that specific <test>
tag.
<suite name="codekru">
<groups>
<run>
<include name="group1" />
</run>
</groups>
<test name="codekruTest">
<classes>
<class name="Test.CodekruTest">
</class>
</classes>
</test>
</suite>
How to run multiple groups together?
We can add more <include> tags inside the <groups> tag to run multiple groups, as shown below.
<groups>
<run>
<include name="group1" />
<include name="group2" />
</run>
</groups>
So, we can use the below XML to run both the groups of the CodekruTest class
<suite name="codekru">
<test name="codekruTest">
<groups>
<run>
<include name="group1" />
<include name="group2" />
</run>
</groups>
<classes>
<class name="Test.CodekruTest">
</class>
</classes>
</test>
</suite>
Output after running the XML file
Executing test1 in CodekruTest class
Executing test2 in CodekruTest class
Executing test3 in CodekruTest class
How to exclude a specific group
There may be situations where you want to run all test cases except for a specific group. In such cases, we can use the <exclude>
tag to specify the name of the group to exclude. By using <exclude name="groupName">
, TestNG will run all test cases except those in the excluded group.
Below XML will execute all the CodekruTest class test cases, except those belonging to “group1“.
<suite name="codekru">
<test name="codekruTest">
<groups>
<run>
<exclude name="group1" />
</run>
</groups>
<classes>
<class name="Test.CodekruTest">
</class>
</classes>
</test>
</suite>
Output –
Executing test2 in CodekruTest class
Executing test4 in CodekruTest class
QnAs on including and excluding groups
What if a single test case belongs to multiple groups? Will it run if we exclude one of the groups?
Let’s look at our CodekruTest class again and assign “test1” to two groups – “group1” and “group2“/
public class CodekruTest {
@Test(groups = { "group1","group2" })
public void test1() {
System.out.println("Executing test1 in CodekruTest class");
Assert.assertTrue(true);
}
@Test(groups = { "group2" })
public void test2() {
System.out.println("Executing test2 in CodekruTest class");
Assert.assertTrue(true);
}
@Test(groups = { "group1" })
public void test3() {
System.out.println("Executing test3 in CodekruTest class");
Assert.assertTrue(true);
}
}
Now, let’s exclude “group1” again and see what happens.
<suite name="codekru">
<test name="codekruTest">
<groups>
<run>
<exclude name="group1" />
</run>
</groups>
<classes>
<class name="Test.CodekruTest">
</class>
</classes>
</test>
</suite>
Output –
Executing test2 in CodekruTest class
We can see here that test1 wasn’t executed because it was part of “group1,” which we excluded from the test execution.
But if we include only “group1” in the execution
<suite name="codekru">
<test name="codekruTest">
<groups>
<run>
<include name="group1" />
</run>
</groups>
<classes>
<class name="Test.CodekruTest">
</class>
</classes>
</test>
</suite>
Output –
Executing test1 in CodekruTest class
Executing test3 in CodekruTest class
In this case, “test1” and “test3” were executed since they belong to group 1. This is how the execution works when a test case belongs to multiple groups.
Now, what if we used both include and exclude tags together? What will happen then?
Just as a recap, “test1” belongs to both – “group1” and “group2”. So, what will happen if we include “group1” in execution but exclude the “group2”.
<suite name="codekru">
<test name="codekruTest">
<groups>
<run>
<include name="group1" />
<exclude name="group2" />
</run>
</groups>
<classes>
<class name="Test.CodekruTest">
</class>
</classes>
</test>
</suite>
Output –
Executing test3 in CodekruTest class
Here, only “test2” was executed because it belonged to “group1.” However, “test1” was not executed, even though it also belonged to “group1,” since “test1” was part of “group2,” which was excluded from execution. Therefore, be cautious when using <include> and <exclude> with groups, especially when a test case is assigned to multiple groups.
Groups of groups
Groups can also include other groups, which are known as MetaGroups. Now, imagine that we want to run all of the groups ( group1 and group2 ) of our CodekruTest class. Here, we can define a new group ( say “all” ) that will contain both groups (group 1 and group 2) and run both of the group’s test cases.
We can define a meta group using the <define> tag as shown below, and then run it using the same <include> tag.
<suite name="codekru">
<test name="codekruTest">
<groups>
<define name="all"> <!-- defining "all" group -->
<include name="group1" />
<include name="group2" />
</define>
<run>
<include name="all" />
</run>
</groups>
<classes>
<class name="Test.CodekruTest">
</class>
</classes>
</test>
</suite>
Output –
Executing test1 in CodekruTest class
Executing test2 in CodekruTest class
Executing test3 in CodekruTest class
Note: Remember to never use the <exclude> tag while defining metagroups.
Use of Regular Expressions while executing groups
Let’s consider three groups: group1, group2, and group3, and we want to run all of them together.
So, what are our options?
One option is to use the <include> tag and mention all of the groups one by one, as shown below –
<groups>
<run>
<include name="group1" />
<include name="group2" />
<include name="group3" />
</run>
</groups>
and there is another option as well, where we can use regular expressions to run all groups that start from the keyword “group,” as shown below
<groups>
<run>
<include name="group.*" />
</run>
</groups>
The XML below can execute all test cases in CodekruTest, where the group name begins with the “group” keyword.
<suite name="codekru">
<test name="codekruTest">
<groups>
<run>
<include name="group.*"/>
</run>
</groups>
<classes>
<class name="Test.CodekruTest">
</class>
</classes>
</test>
</suite>
If you’re interested in learning about different regex symbols, we recommend checking out this article.
Groups at the class level
We can assign groups at the class level, which means all the methods in that class will automatically belong to the assigned group. Additionally, if we assign a specific group to a particular test method within the class, that method will then belong to both the class-level group and its own individual group.
@Test(groups = {"classGroup"})
public class CodekruTest {
@Test(groups = { "group1" })
public void test1() {
System.out.println("Executing test1 in CodekruTest class");
Assert.assertTrue(true);
}
@Test(groups = { "group2" })
public void test2() {
System.out.println("Executing test2 in CodekruTest class");
Assert.assertTrue(true);
}
}
In this example, “test1” is part of both the “group1” and “classGroup” groups, while “test2” is part of both the “group2” and “classGroup” groups. Therefore, if we choose to run only the “classGroup” group, both “test1” and “test2” methods will be executed.
<suite name="codekru">
<test name="codekruTest">
<groups>
<run>
<include name="classGroup"/>
</run>
</groups>
<classes>
<class name="Test.CodekruTest">
</class>
</classes>
</test>
</suite>
Output –
Executing test1 in CodekruTest class
Executing test2 in CodekruTest class
Note: @BeforeGroups and @AfterGroups annotations are used along with groups to perform setup or cleanup activities for a group.
We hope you have liked the article. If you have any doubts or concerns, please feel free to write us in comments or mail us at admin@codekru.com.