TestNG annotations – @AfterGroups annotation

We have written about how to make groups in TestNG and what is the use of making groups in our previous post. Please read that post to have a better understanding of the groups. And we have also talked about the @BeforeGroups annotation, so in this post, we will discuss the @AfterGroups annotation.

@AfterGroups annotated method executes after test cases inside the mentioned group have been executed.

Syntax of using the @AfterGroups annotation

@AfterGroups(groups = {"group1","group2","...."})
public void afterGroups() {
}

We have to pass the list of groups in the “groups” attribute for which we want to run the @AfterGroups annotated method.

Example

We will take a CodekruTest class consisting of two test cases. Both cases belong to a group called “group1“.

package Test;

import org.testng.Assert;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.Test;

public class CodekruTest {

	@AfterGroups(groups = "group1")
	public void afterGroup() {
		System.out.println("afterGroup method executed");
	}

	@Test(groups = { "group1" })
	public void test1() {
		System.out.println("Executing test1 in CodekruTest class");
		Assert.assertTrue(true);
	}

	@Test(groups = { "group1" })
	public void test2() {
		System.out.println("Executing test2 in CodekruTest class");
		Assert.assertTrue(true);
	}

}

Now, to run the cases of the group, we will have to execute the below XML file. You can look at this post to understand the working of a group.

<suite name="codekru">
	<test name="codekruTest">
		<groups>
			<run>
				<include name="group1" />
			</run>
		</groups>
		<classes>
			<class name="Test.CodekruTest" />
		</classes>
	</test>
</suite>

Output after running the above XML file –

Executing test1 in CodekruTest class
Executing test2 in CodekruTest class
afterGroup method executed

===============================================
codekru
Total tests run: 2, Passes: 2, Failures: 0, Skips: 0
When will @AfterGroups annotated method be executed with respect to other @AfterXXX annotations?
package Test;

import org.junit.AfterClass;
import org.testng.Assert;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterTest;
import org.testng.annotations.Test;

public class CodekruTest {

	@AfterSuite
	public void afterSuite() {
		System.out.println("afterSuite method executed");
	}

	@AfterClass
	public void afterClass() {
		System.out.println("afterClass method executed");
	}

	@AfterMethod
	public void afterMethod() {
		System.out.println("afterMethod method executed");
	}

	@AfterTest
	public void afterTest() {
		System.out.println("afterTest method executed");
	}

	@AfterGroups(groups = "group1")
	public void afterGroup() {
		System.out.println("afterGroup method executed");
	}

	@Test(groups = { "group1" })
	public void test1() {
		System.out.println("Executing test1 in CodekruTest class");
		Assert.assertTrue(true);
	}

}

Below is our XML file to run the CodekruTest class.

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >

<suite name="codekru">
	<test name="codekruTest">
		<groups>
			<run>
				<include name="group1" />
			</run>
		</groups>
		<classes>
			<class name="Test.CodekruTest" />
		</classes>
	</test>
</suite>

Output after running the above XML file –

Executing test1 in CodekruTest class
afterGroup method executed

Why are annotated methods other than afterGroup() not executed?

This is because they were not using the “groups” attribute with the annotations. But, if we use it, we will be able to see the order of execution of the @AfterGroups annotation with respect to other annotations.

package Test;

import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterTest;
import org.testng.annotations.Test;

public class CodekruTest {

	@AfterSuite(groups = "group1")
	public void afterSuite() {
		System.out.println("afterSuite method executed");
	}

	@AfterClass(groups = "group1")
	public void afterClass() {
		System.out.println("afterClass method executed");
	}

	@AfterMethod(groups = "group1")
	public void afterMethod() {
		System.out.println("afterMethod method executed");
	}

	@AfterTest(groups = "group1")
	public void afterTest() {
		System.out.println("afterTest method executed");
	}

	@AfterGroups(groups = "group1")
	public void afterGroup() {
		System.out.println("afterGroup method executed");
	}

	@Test(groups = { "group1" })
	public void test1() {
		System.out.println("Executing test1 in CodekruTest class");
		Assert.assertTrue(true);
	}

}

Output after rerunning the XML file

Executing test1 in CodekruTest class
afterMethod method executed
afterGroup method executed
afterClass method executed
afterTest method executed
afterSuite method executed

===============================================
codekru
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0

This gives a clear understanding of the order of execution for various annotations.

The What If scenarios

Q – What if we place test cases belonging to a single group in different packages?

We will take two classes ( CodekruTest1 and CodekruTest2 ) and place them in different packages and then try to use the @AfterGroups annotation.

CodekruTest1.java in package Practice.Test1

package Practice.Test1;

import org.testng.Assert;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.Test;

public class CodekruTest1 {

	@AfterGroups(groups = "group1")
	public void afterGroup() {
		System.out.println("afterGroup method executed");
	}

	@Test(groups = { "group1" })
	public void test1() {
		System.out.println("Executing test1 in CodekruTest1 class");
		Assert.assertTrue(true);
	}
}

CodekruTest2.java in package Practice.Test2

package Practice.Test2;

import org.testng.Assert;
import org.testng.annotations.Test;

public class CodekruTest2 {
	
	@Test(groups = { "group1" })
	public void test1() {
		System.out.println("Executing test1 in CodekruTest2 class");
		Assert.assertTrue(true);
	}
}

We will run the below XML file and see what happens now.

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >

<suite name="codekru">
	<test name="codekruTest">
		<groups>
			<run>
				<include name="group1" />
			</run>
		</groups>
		<classes>
			<class name="Practice.Test1.CodekruTest1" />
			<class name="Practice.Test2.CodekruTest2" />
		</classes>
	</test>
</suite>

Output of above XML file –

Executing test1 in CodekruTest1 class
Executing test1 in CodekruTest2 class
afterGroup method executed

===============================================
codekru
Total tests run: 2, Passes: 2, Failures: 0, Skips: 0
===============================================

So, what happened here?

As, By default, TestNG will run our tests in the order they are found in the XML file. Below is the sequence with which the XML file got executed –

  • TestNG encountered the CodekruTest1 class and executed cases that belonged to group1. All cases belonging to group1 haven’t been executed, so the @AfterGroups annotated method won’t be executed yet.
  • And then, TestNG encountered the CodekruTest2 class and executed the cases that belonged to group1.
  • After the execution of cases is finished and no more classes are found. TestNG will now execute the @AfterGroups annotated method.
Q – How will @AfterGroups annotation behave when placed over a superclass?
class CodekruTest{
	@AfterGroups(groups = "group1")
	public void afterGroup() {
		System.out.println("afterGroup method executed in superclass");
	}
	
}

public class CodekruTestSubclass extends CodekruTest{

	@Test(groups = { "group1" })
	public void test1() {
		System.out.println("Executing test1 in CodekruTestSubclass");
		Assert.assertTrue(true);
	}

}

Below is the XML file to run the subclass.

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="codekru">
	<test name="codekruTest">
		<classes>
			<class name="Test.CodekruTestSubclass">
			</class>
		</classes>
	</test>
</suite>

Output –

Executing test1 in CodekruTestSubclass
afterGroup method executed in superclass

We can see here that the afterGroup() method was executed because the subclass inherited the superclass methods. So, if we make the afterGroup() private, it won’t be executed.

Please visit this article to learn more about TestNG annotations.

We hope that you have liked the article. If you have any doubts or concerns, please feel free to write us in the comments or mail us at admin@codekru.com.

Other TestNG annotations
Liked the article? Share this on

Leave a Comment

Your email address will not be published. Required fields are marked *