TestNG Lifecycle Annotation Scopes
Understanding the execution order is critical for framework design.
Full Execution Order
CODE
@BeforeSuite → runs ONCE at very start of entire suite
@BeforeTest → runs once per <test> block in testng.xml
@BeforeClass → runs once before first @Test method in each class
@BeforeMethod → runs before EACH @Test method
@Test ← actual test
@AfterMethod → runs after EACH @Test method
@AfterClass → runs once after all @Test methods in class
@AfterTest → runs once after all tests in <test> block
@AfterSuite → runs ONCE at very end of suite
Practical Example
Java
public class SuiteSetup {
@BeforeSuite
public void globalSetup() {
// Runs ONCE: Start test database, initialize ExtentReports,
// load global config, start mock server
System.out.println("Suite started");
ExtentReportManager.getInstance();
TestDatabase.startTestDb();
}
@AfterSuite
public void globalTeardown() {
// Runs ONCE: Flush reports, stop test database, send email
ExtentReportManager.getInstance().flush();
TestDatabase.stopTestDb();
EmailUtility.sendReport();
}
}
public class LoginTest extends BaseTest {
@BeforeClass
public void loginSetup() {
// Runs ONCE per class: Navigate to login page, set browser cookies
driver.get(config.get("baseUrl") + "/login");
}
@AfterClass
public void loginCleanup() {
// Runs ONCE per class: Logout, clear session
driver.findElement(By.id("logoutBtn")).click();
}
@BeforeMethod
public void beforeEachTest(Method method) {
// Runs before EVERY @Test: Take note of test name, create ExtentTest entry
ExtentReportManager.setTest(
ExtentReportManager.getInstance().createTest(method.getName())
);
}
@AfterMethod
public void afterEachTest(ITestResult result) {
// Runs after EVERY @Test: Screenshot on fail, log status
if (result.getStatus() == ITestResult.FAILURE) {
captureScreenshot(result.getName());
ExtentReportManager.getTest().fail(result.getThrowable());
} else {
ExtentReportManager.getTest().pass("Test passed");
}
}
@Test
public void validLogin() { ... }
@Test
public void invalidLogin() { ... }
}
What Each Scope Is Best For
| Annotation | Use For |
|---|---|
@BeforeSuite | Start report framework, launch test server, global config |
@AfterSuite | Flush reports, send email, stop services |
@BeforeTest | Setup per-XML-test-block (e.g., browser type for cross-browser) |
@AfterTest | Tear down per-XML-test-block |
@BeforeClass | Login once for all methods in class, navigate to section |
@AfterClass | Logout, clean test data created by class |
@BeforeMethod | Create ExtentTest entry, reset form, navigate to page |
@AfterMethod | Screenshot on fail, log result, reset state |
Key Rules
- ✓
@BeforeSuitemethod must be in a class that is part of the suite (or a listener) - ✓
@BeforeTestcorresponds to<test>in testng.xml — NOT a@Testmethod - ✓Multiple
@BeforeMethodmethods execute in class hierarchy order (parent first) - ✓
alwaysRun = trueon@AfterMethodensures cleanup even when test throws
