This is the single most important lesson in TestNG. If you understand annotations and their execution order, everything else falls into place. This topic comes up in literally every Selenium interview.
Think of annotations like labels on a kitchen station. One label says "Prep before service," another says "Clean after service," another says "Do this before every dish." TestNG reads these labels and runs your methods in the right order automatically.
| Annotation | When It Runs | Real-World Use |
|---|---|---|
| @BeforeSuite | Once before ALL tests in the suite | Start test environment, seed database, load global config |
| @AfterSuite | Once after ALL tests in the suite | Stop environment, send report email, clean up database |
| @BeforeTest | Before all classes in a <test> tag | Shared setup across multiple test classes |
| @AfterTest | After all classes in a <test> tag | Shared teardown across multiple test classes |
| @BeforeGroups | Before first method of a group | Group-specific setup (e.g., setup for "smoke" group) |
| @AfterGroups | After last method of a group | Group-specific cleanup |
| @BeforeClass | Once before first test in the class | Load test data, initialize shared objects |
| @AfterClass | Once after last test in the class | Release class-level resources |
| @BeforeMethod | Before EACH test method | Launch browser, navigate to URL — MOST USED in Selenium |
| @AfterMethod | After EACH test method | Close browser — MOST USED in Selenium |
| @Test | The actual test | Your test logic, actions, and assertions |
Here is a complete example. Run this and study the output carefully:
import org.testng.annotations.*;
public class AnnotationOrderDemo {
@BeforeSuite
public void beforeSuite() {
System.out.println("1. @BeforeSuite — runs ONCE before everything");
}
@BeforeTest
public void beforeTest() {
System.out.println("2. @BeforeTest — runs once per <test> tag");
}
@BeforeClass
public void beforeClass() {
System.out.println("3. @BeforeClass — runs ONCE before first test in class");
}
@BeforeMethod
public void beforeMethod() {
System.out.println(" 4. @BeforeMethod — runs before EACH test");
}
@Test(priority = 1)
public void testLogin() {
System.out.println(" 5. @Test — testLogin executing");
}
@Test(priority = 2)
public void testDashboard() {
System.out.println(" 5. @Test — testDashboard executing");
}
@AfterMethod
public void afterMethod() {
System.out.println(" 6. @AfterMethod — runs after EACH test");
}
@AfterClass
public void afterClass() {
System.out.println("7. @AfterClass — runs ONCE after last test in class");
}
@AfterTest
public void afterTest() {
System.out.println("8. @AfterTest — runs once per <test> tag");
}
@AfterSuite
public void afterSuite() {
System.out.println("9. @AfterSuite — runs ONCE after everything");
}
}1. @BeforeSuite — runs ONCE before everything
2. @BeforeTest — runs once per <test> tag
3. @BeforeClass — runs ONCE before first test in class
4. @BeforeMethod — runs before EACH test
5. @Test — testLogin executing
6. @AfterMethod — runs after EACH test
4. @BeforeMethod — runs before EACH test
5. @Test — testDashboard executing
6. @AfterMethod — runs after EACH test
7. @AfterClass — runs ONCE after last test in class
8. @AfterTest — runs once per <test> tag
9. @AfterSuite — runs ONCE after everythingNotice how @BeforeMethod and @AfterMethod run before and after EACH test. But @BeforeClass runs only once. This is the key difference that interviewers look for.
In 90% of Selenium projects, here is what goes where:
The most common beginner mistake is putting browser setup in @BeforeClass instead of @BeforeMethod. If one test changes the page state (navigates away, logs out), the next test starts on the wrong page. Use @BeforeMethod so each test gets a clean browser.
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.*;
import java.time.Duration;
public class BankingBaseTest {
protected WebDriver driver;
protected WebDriverWait wait;
@BeforeMethod
public void setUp() {
driver = new ChromeDriver();
driver.manage().window().maximize();
wait = new WebDriverWait(driver, Duration.ofSeconds(10));
driver.get("https://www.testerrank.com/banking");
}
@AfterMethod
public void tearDown() {
if (driver != null) {
driver.quit();
}
}
}Always check if driver is not null before calling quit(). If the browser fails to launch (wrong driver version, ChromeDriver not found), driver will be null and calling quit() will throw a NullPointerException, hiding the real error.
Q: What is the execution order of TestNG annotations?
A: @BeforeSuite → @BeforeTest → @BeforeClass → @BeforeMethod → @Test → @AfterMethod → @AfterClass → @AfterTest → @AfterSuite. The key insight: @BeforeSuite, @BeforeTest, and @BeforeClass run once. @BeforeMethod runs before every single @Test method. In Selenium, @BeforeMethod is the most used annotation — it launches the browser and navigates to the URL before each test.
Q: What annotations have you used in your framework?
A: In my framework, @BeforeMethod launches the browser, maximizes it, and navigates to the application URL — giving each test a fresh browser. @AfterMethod calls driver.quit() to close the browser and free resources. @Test marks every test method with attributes like priority, groups, and description. @BeforeClass loads test data and configuration. @BeforeSuite handles global setup like reading environment variables and configuring the test environment.
Key Point: Execution order: @BeforeSuite → @BeforeTest → @BeforeClass → @BeforeMethod → @Test → @AfterMethod → @AfterClass → @AfterTest → @AfterSuite.