TestNG annotations – @AfterClass annotation

AfterClass annotation

Earlier, we talked about the @BeforeClass annotation of TestNG, and in this post, we will discuss the @AfterClass annotation in TestNG. @AfterClass annotated method will run after all of the test cases in a particular class have run. This can help us do some cleaning or resetting activities after running all of the test cases in a class.

So, when does this @AfterClass annotated method will be executed?

 Below XML will help you understand the exact execution point of the annotated method.

<suite name="codekru">
	<test name="codekru">
		<classes>
			<class name="Test.CodekruTestFirst"> <!-- @BeforeClass method of CodekruTestFirst class will execute here -->
				<methods>
					<include name="testMethod" />
				</methods>
			</class>  <!-- @AfterClass method of CodekruTestFirst class will execute here -->
			<class name="Test.CodekruTestSecond">  <!-- @BeforeClass method of CodekruTestSecond class will execute here -->
				<methods>
					<include name="testMethod" />
				</methods>
			</class> <!-- @AfterClass method of CodekruTestSecond class will execute here -->
		</classes>
	</test>
</suite>

Now, we will take two classes (CodekruTestFirst and CodekruTestSecond), and we will keep one @AfterClass annotated method in each of the classes.

CodekruTestFirst.java

package Test;

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

public class CodekruTestFirst {

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

	@Test
	public void testMethod() {
		System.out.println("Executing the test in CodekruTestFirst class");
		Assert.assertTrue(true);
	}

}

CodekruTestSecond.java

package Test;

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

public class CodekruTestSecond {

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

	@Test
	public void testMethod() {
		System.out.println("Executing the test in CodekruTestSecond class");
		Assert.assertTrue(true);
	}

}

Now, we will run the below XML file

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

<suite name="codekru">
	<test name="codekru">
		<classes>
			<class name="Test.CodekruTestFirst">
				<methods>
					<include name="testMethod" />
				</methods>
			</class>  <!-- @AfterClass method of CodekruTestFirst class will execute here -->
			<class name="Test.CodekruTestSecond">
				<methods>
					<include name="testMethod" />
				</methods>
			</class> <!-- @AfterClass method of CodekruTestFirst class will execute here -->
		</classes>
	</test>
</suite>

Output –

Executing the test in CodekruTestFirst class
afterClass method in CodekruTestFirst class
Executing the test in CodekruTestSecond class
afterClass method in CodekruTestSecond class

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

Now, what happened here?  

  • By default, TestNG will run our tests in the order found in the XML file. So, it got CodekruTestFirst class, ran its test method, and then its @AfterClass annotated method.
  • And after that, it went for the CodekruTestSecond class, ran its test cases, and then its @AfterClass annotated method.
So, can we put more than one @AfterClass annotated method in one class?

Yes, we can put more than one @AfterClass annotated method in one class, and then all of these annotated methods will run after all of the test cases have been executed for that class. Let’s look at it with an example.

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

public class CodekruTestSecond {

	@AfterClass
	public void afterClass1() {
		System.out.println("in afterClass1 method");
	}

	@AfterClass
	public void afterClass2() {
		System.out.println("in afterClass2 method");
	}

	@Test
	public void testMethod() {
		System.out.println("Executing the test in CodekruTestSecond class");
		Assert.assertTrue(true);
	}

}

We will run the below XML file to execute the CodekruTestSecond class.

<suite name="codekru">
	<test name="codekruTest">
		<classes>
			<class name="Test.CodekruTestSecond" />
		</classes>
	</test>
</suite>

Output after running the XML file –

Executing the test in CodekruTestSecond class
in afterClass1 method
in afterClass2 method

===============================================
codekru
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
How does @AfterClass annotation work when placed on a superclass?

Let’s take a look at this with an example.

package Test;

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

class CodekruTest {

	@AfterClass
	public void afterClassMethod() {
		System.out.println("afterClassMethod called");
	}

}

public class CodekruTestSubclass extends CodekruTest {

	@Test()
	public void test() {
		System.out.println("Executing the subclass test");
		Assert.assertTrue(true);
	}

}

And now, we will run below testng.xml and see what happens.

<suite name="codekru">
	<test name="codekru">
		<classes>
			<class name="Test.CodekruTestSubclass" />
		</classes>
	</test>
</suite>

Output –

Executing the subclass test
afterClassMethod called

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

So, the afterClassMethod was executed even if it was present in the superclass. This is because the afterClassMethod was inherited by the subclass. But, if we make afterClassMethod private, it won’t run as private methods cannot be inherited by the subclass.

If you want to learn more about TestNG annotation, we recommend you read this article.

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

Other TestNG annotations
Liked the article? Share this on

Leave a Comment

Your email address will not be published.