TestNG Groups in detail with examples

Sometimes we have to divide our test cases into various sets to identify the scenarios that they are verifying. Like, we can have a set of test cases that will only determine the functionality of the system, and then another set of test cases that will verify the UI part of the system, and many more like this. These sets of test cases are called groups in TestNG. So, TestNG allows us to create a grouping of various test methods or cases irrespective of their location in the project. ( They might be in a different class, different package ) etc.

Some points to remember about TestNG Groups –

  • TestNG groups are represented by the <groups> tag.
  • A test case can belong to one or more groups. Eg. – A test case can be a part of the sanity group and the functional group too.
  • Groups can include other groups. These groups are known as MetaGroups.
  • We can include specific groups in the XML file so that only those groups run while executing the XML file.
  • Similarly, we can also exclude groups so that all groups run except the excluded ones.
  • Groups can be found under the <suite> tag or the <test> tag. <groups> tags specified in the <suite> tag will apply to all of the <test> tags underneath it but those specified in the <test> tag will be limited to that test only.
  • We can define the groups at the class level too. And then all of the test methods in that class will belong to that group.

Now, let’s move on to making groups in TestNG.

Now how can we make a test case, a part of the group? We have to use the groups attribute of the TestNG annotation

@Test(groups = { "groupName1","groupName2" })

We will be taking two groups – group1 and group2 to show you how groups work in TestNG. Below is our CodekruTest class where we will have our test methods which will belong to different groups.

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);
	}

}

Below is the XML file to run group1 only

<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

You can see that only the test cases belonging to group1 got executed. This is how we can run only some specific groups.

Now, how can we exclude groups?

For this, we have to use the <exclude> tag instead of the <include> one written in the above XML file. So, if we want to exclude group1 from running, then we will be making our TestNG XML file in the below manner

<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

So, here all other groups except the group1 will be executed.

What if a single test case belongs to multiple groups? Will it run if we exclude one of the groups?

Let’s take a look at our CodekruTest class again and include one of the test cases (say test1 ) into both of the 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 but what if we use include groups functionality now?

<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

So, you can see here that both test1() and test3() methods got executed and this is how tests belonging to multiple groups work in TestNG.

Now, what if we used both include and exclude tags in the same XML file? What will happen then?

Hmm, that seems to be interesting, so, let’s try it

<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

In this case, test1 wasn’t run and only test3 got executed as it belonged to group1.

Now when would we require such types of scenarios where we need to use both include and exclude groups functionality?

Test cases break all the time but sometimes we just don’t get the time to fix it. So, let’s just say that we have a test case that belongs to a functional group as it tests the functionality of the system but now is broken due to some reason. We can put that test into a broken group and just exclude it from executing and so we can put all such test cases in that broken group and refrain the group itself from executing.

@Test(groups = { "functional","broken" })
public void testName()

Groups of groups

Groups can also include other groups and these groups 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 of the groups ( group1 and group2 ) and will run both of the group’s test cases.

<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, never to use the <exclude> tag while defining groups.

Use of Regular Expressions while executing groups

Suppose we have several groups like group1, group2. group3 and so on. Now, we want to execute all those groups but it would be tiresome if we use <include> tag on all of the groups one by one. What we can do in this scenario is make use of the regular expressions here as shown.

We modified our CodekruTest class a bit to include a bit more groups.

<suite name="codekru">
	<test name="codekruTest">
		<groups>
			<run>
				<include name="group.*"/>
			</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
Executing test4 in CodekruTest class

If you want to know about various regex symbols, then we suggest you to giving this article a read.

Making Groups at class level

We can also make groups at the class level. If we do that, then all of the methods of that class will belong to that group. And if we also decided to give a test method of the class, a group of its own, then that test method will now belong to two groups.

@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);
	}

}

Here test1() belongs with both group1 and classGroup and test2() also belongs with two groups ( group2 and classGroup). Now, Let’s run the classGroup group and see what happens.

<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

There are two TestNG annotations (@BeforeGroups and @AfterGroups) that work around groups and help us to do some setup or cleanup work for a particular group.

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 [email protected]

Liked the article? Share this on

Leave a Comment

Your email address will not be published.