Annotation Execution Hierarchy ⭐
TestNG executes annotations from the outermost scope to the innermost scope in the following order:
@BeforeSuite
@BeforeTest
@BeforeClass
@BeforeMethod
@Test
@AfterMethod
@AfterClass
@AfterTest
@AfterSuite
Annotation Lifecycle
| Annotation | Executes |
@BeforeSuite / @AfterSuite |
Once for the entire test suite |
@BeforeTest / @AfterTest |
Once for each <test> section in testng.xml |
@BeforeClass / @AfterClass |
Once before and after each test class |
@BeforeMethod / @AfterMethod |
Before and after every @Test method |
@Test |
The actual test method |
Typical Framework Usage
@BeforeMethod→ Launch browser and initialize test data.@AfterMethod→ Capture screenshots on failure and close the browser.
@Test Attributes
| Attribute | Example | Purpose |
priority |
@Test(priority = 1) |
Controls execution order |
groups |
@Test(groups = {"smoke"}) |
Assigns tests to groups |
dependsOnMethods |
@Test(dependsOnMethods = "login") |
Executes only if another method passes |
dependsOnGroups |
@Test(dependsOnGroups = "setup") |
Depends on an entire group |
enabled |
@Test(enabled = false) |
Disables the test |
invocationCount |
@Test(invocationCount = 3) |
Executes the test multiple times |
timeOut |
@Test(timeOut = 5000) |
Fails if execution exceeds the specified time |
dataProvider |
@Test(dataProvider = "users") |
Supplies test data |
expectedExceptions |
@Test(expectedExceptions = ...) |
Passes only if the expected exception occurs |
Priority Rules
- No priority specified → Default priority is 0.
- Lower priority executes first.
- When priorities are equal, execution follows method name order.
Assertions
| Assertion Type | Behavior |
Hard Assertion (Assert) |
Test execution stops immediately after a failed assertion |
Soft Assertion (SoftAssert) |
Test execution continues, and all failures are reported at assertAll() |
Hard Assertions
Assert.assertEquals(actual, expected);
Assert.assertTrue(condition);
Assert.assertNotNull(object);
Soft Assertions
SoftAssert sa = new SoftAssert();
sa.assertEquals(actual, expected);
sa.assertAll();
Important: Always call
assertAll()when usingSoftAssert.
DataProvider (Data-Driven Testing)
@DataProvider(name = "loginData")
public Object[][] getData() {
return new Object[][]{
{"admin", "admin123"},
{"user", "user123"}
};
}
@Test(dataProvider = "loginData")
public void loginTest(String username, String password) {
// Test implementation
}
Key Points
- Return type:
Object[][] - Each inner array represents one test execution.
- Commonly used for Data-Driven Testing.
testng.xml
<suite name="RegressionSuite" parallel="tests" thread-count="3">
<test name="ChromeTests">
<parameter name="browser" value="chrome"/>
<groups>
<run>
<include name="smoke"/>
</run>
</groups>
<classes>
<class name="tests.LoginTest"/>
</classes>
</test>
</suite>
Important Attributes
| Attribute | Common Values |
parallel |
methods, classes, tests, instances |
thread-count |
Number of parallel execution threads |
Additional Configuration
<include>and<exclude>control test execution.<parameter>passes values to@Parameters.
Listeners ⭐
Implement ITestListener to execute custom actions during different stages of test execution.
Advertisement
| Listener Method | Triggered When |
onTestStart() |
Test execution begins |
onTestSuccess() |
Test passes |
onTestFailure() |
Test fails (commonly used for screenshots) |
onTestSkipped() |
Test is skipped |
onFinish() |
Entire test execution completes |
Registering a Listener
Using annotation:
@Listeners(MyListener.class)
Or using testng.xml:
<listeners>
<listener class-name="listeners.MyListener"/>
</listeners>
Common TestNG Tasks
| Task | Solution |
| Re-run Failed Tests | Execute the auto-generated testng-failed.xml |
| Retry Failed Tests | Implement IRetryAnalyzer |
| Execute a Group | Use <include name="smoke"/> |
| Skip a Test | @Test(enabled = false) or throw new SkipException() |
| Execute with Maven | Configure Maven Surefire Plugin |
| Generate Reports | View reports under the test-output directory |
Go Deeper
Continue learning with: