Interview Prep
Interview Questions on TestNG — Annotations, DataProvider, Parallel Execution & Listeners
TestNG is the default test framework for Selenium automation in India. Every QA automation interview — from service companies to product companies — tests your TestNG knowledge. Here are the questions that actually get asked, with code examples and XML configuration.

TestNG powers most Selenium automation frameworks in Indian IT. If you do QA automation, you need to master this.
TestNG in Indian QA Interviews
TestNG is the backbone of Selenium test automation in India. Whether you are interviewing at TCS, Infosys, Wipro, or product companies like Flipkart and Paytm, TestNG questions are guaranteed in any QA automation interview. The framework provides annotations, data-driven testing, parallel execution, and reporting — everything you need to build a production-grade automation framework.
TestNG interviews test three things: annotation knowledge (execution order, lifecycle), configuration skills (testng.xml, groups, parameters), and advanced features (DataProvider, parallel execution, listeners). Freshers get annotation and XML questions. Experienced candidates get framework design and custom listener questions.
This guide covers the 10 TestNG questions most commonly asked in Indian QA automation interviews — with actual code examples and XML configurations.
The first TestNG question is always: “What is the execution order of TestNG annotations?” If you cannot recite this from memory, the interviewer assumes you have not used TestNG in a real project.
Annotations
Q1: What are TestNG annotations? What is the execution order?
TestNG Annotations — Execution Order:
@BeforeSuite → runs once before ALL tests in suite
@BeforeTest → runs before each <test> tag in XML
@BeforeClass → runs once before all methods in class
@BeforeMethod → runs before EACH @Test method
@Test → the actual test method
@AfterMethod → runs after EACH @Test method
@AfterClass → runs once after all methods in class
@AfterTest → runs after each <test> tag in XML
@AfterSuite → runs once after ALL tests in suite
Visual flow for 2 test methods:
┌─ @BeforeSuite ─────────────────────────────┐
│ ┌─ @BeforeTest ──────────────────────────┐│
│ │ ┌─ @BeforeClass ────────────────────┐ ││
│ │ │ @BeforeMethod → @Test1 → @AfterMethod ││
│ │ │ @BeforeMethod → @Test2 → @AfterMethod ││
│ │ └─ @AfterClass ─────────────────────┘ ││
│ └─ @AfterTest ───────────────────────────┘│
└─ @AfterSuite ──────────────────────────────┘
// Example:
public class LoginTest {
@BeforeSuite
public void setupSuite() { /* DB connection */ }
@BeforeClass
public void setupDriver() { /* WebDriver init */ }
@BeforeMethod
public void openLoginPage() { /* navigate to URL */ }
@Test
public void testValidLogin() { /* test code */ }
@Test
public void testInvalidLogin() { /* test code */ }
@AfterMethod
public void clearCookies() { /* cleanup */ }
@AfterClass
public void quitDriver() { /* driver.quit() */ }
}Q2: What is the difference between @BeforeMethod and @BeforeClass?
@BeforeClass:
- Runs ONCE before all test methods in the class
- Use for: one-time setup (driver init, DB connection)
- Equivalent to JUnit's @BeforeAll
@BeforeMethod:
- Runs before EACH test method
- Use for: per-test setup (navigate to page, reset data)
- Equivalent to JUnit's @BeforeEach
Example with 3 test methods:
@BeforeClass → executes 1 time
@BeforeMethod → @Test1 → @AfterMethod
@BeforeMethod → @Test2 → @AfterMethod
@BeforeMethod → @Test3 → @AfterMethod
@AfterClass → executes 1 time
// Practical example:
public class CartTest {
@BeforeClass
public void setup() {
// Runs ONCE: launch browser, login
driver = new ChromeDriver();
loginAsUser("testuser", "password");
}
@BeforeMethod
public void goToCart() {
// Runs before EACH test: navigate to cart page
driver.get("https://shop.com/cart");
clearCart(); // ensure clean state
}
@Test public void testAddItem() { /* ... */ }
@Test public void testRemoveItem() { /* ... */ }
@Test public void testCheckout() { /* ... */ }
@AfterClass
public void teardown() {
// Runs ONCE: close browser
driver.quit();
}
}Q3: How do you skip a test or set priority?
// Skip a test:
@Test(enabled = false) // test will NOT run
public void testFeatureNotReady() {
// This test is skipped during execution
}
// Set priority (execution order):
@Test(priority = 1)
public void testLogin() { /* runs first */ }
@Test(priority = 2)
public void testDashboard() { /* runs second */ }
@Test(priority = 3)
public void testLogout() { /* runs third */ }
// Default priority is 0
// Lower number = runs first
// Same priority = alphabetical order
// Other useful @Test attributes:
@Test(
priority = 1,
enabled = true,
description = "Verify login with valid credentials",
groups = {"smoke", "regression"},
dependsOnMethods = {"testSetup"},
timeOut = 5000, // fail if takes > 5 seconds
invocationCount = 3, // run 3 times
expectedExceptions = {ArithmeticException.class}
)
// dependsOnMethods example:
@Test
public void testLogin() { /* must pass first */ }
@Test(dependsOnMethods = {"testLogin"})
public void testDashboard() {
// Skipped if testLogin fails
}testng.xml Configuration
Q4: What is testng.xml? Write a sample configuration.
testng.xml = XML configuration file that controls:
- Which tests to run
- Test suite organization
- Parameters, listeners, groups
- Parallel execution settings
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Regression Suite" verbose="1">
<!-- Parameters available to all tests -->
<parameter name="browser" value="chrome"/>
<parameter name="environment" value="staging"/>
<!-- Listeners -->
<listeners>
<listener class-name="com.project.listeners.TestListener"/>
<listener class-name="com.project.listeners.ReportListener"/>
</listeners>
<!-- Test 1: Login Module -->
<test name="Login Tests">
<classes>
<class name="com.project.tests.LoginTest">
<methods>
<include name="testValidLogin"/>
<include name="testInvalidLogin"/>
<exclude name="testForgotPassword"/>
</methods>
</class>
</classes>
</test>
<!-- Test 2: Cart Module -->
<test name="Cart Tests">
<classes>
<class name="com.project.tests.CartTest"/>
<class name="com.project.tests.CheckoutTest"/>
</classes>
</test>
</suite>
<!-- Hierarchy: suite → test → classes → class → methods -->Q5: How do you group tests in TestNG?
// Step 1: Assign groups to test methods
@Test(groups = {"smoke"})
public void testLogin() { /* ... */ }
@Test(groups = {"smoke", "regression"})
public void testDashboard() { /* ... */ }
@Test(groups = {"regression"})
public void testReportGeneration() { /* ... */ }
@Test(groups = {"regression", "database"})
public void testDataExport() { /* ... */ }
// Step 2: Configure groups in testng.xml
<suite name="Suite">
<test name="Smoke Tests">
<groups>
<run>
<include name="smoke"/>
</run>
</groups>
<classes>
<class name="com.project.tests.LoginTest"/>
<class name="com.project.tests.DashboardTest"/>
</classes>
</test>
<!-- Exclude specific groups -->
<test name="Regression Without DB">
<groups>
<run>
<include name="regression"/>
<exclude name="database"/>
</run>
</groups>
<classes>
<class name="com.project.tests.AllTests"/>
</classes>
</test>
</suite>
// Why groups matter:
// - Run only smoke tests before deployment
// - Run full regression on nightly builds
// - Exclude slow/flaky tests from CI pipeline
// - Organize by feature, priority, or typeData-Driven Testing
Q6: What is @DataProvider? How does it work?
@DataProvider = supplies test data to test methods
Returns Object[][] (2D array of test data)
Each row = one test execution with different data
// DataProvider method
@DataProvider(name = "loginData")
public Object[][] getLoginData() {
return new Object[][] {
{"admin@test.com", "admin123", true},
{"user@test.com", "user123", true},
{"invalid@test.com", "wrong", false},
{"", "", false},
{"admin@test.com", "", false},
};
}
// Test method using DataProvider
@Test(dataProvider = "loginData")
public void testLogin(String email, String password,
boolean expectedResult) {
LoginPage loginPage = new LoginPage(driver);
loginPage.enterEmail(email);
loginPage.enterPassword(password);
loginPage.clickLogin();
if (expectedResult) {
Assert.assertTrue(loginPage.isDashboardDisplayed(),
"Login should succeed for: " + email);
} else {
Assert.assertTrue(loginPage.isErrorDisplayed(),
"Login should fail for: " + email);
}
}
// This runs 5 times — once for each data row
// Report shows each iteration separately
// If row 3 fails, rows 1,2,4,5 still run
// DataProvider from another class:
@Test(dataProvider = "loginData",
dataProviderClass = TestData.class)
public void testLogin(String email, String password) {}Q7: How do you read test data from Excel?
// Use Apache POI library to read Excel files
// Maven dependency:
// <dependency>
// <groupId>org.apache.poi</groupId>
// <artifactId>poi-ooxml</artifactId>
// <version>5.2.3</version>
// </dependency>
// Excel utility class:
public class ExcelUtils {
public static Object[][] readExcelData(String filePath,
String sheetName) {
try {
FileInputStream fis = new FileInputStream(filePath);
Workbook workbook = new XSSFWorkbook(fis);
Sheet sheet = workbook.getSheet(sheetName);
int rowCount = sheet.getLastRowNum();
int colCount = sheet.getRow(0).getLastCellNum();
Object[][] data = new Object[rowCount][colCount];
for (int i = 1; i <= rowCount; i++) {
Row row = sheet.getRow(i);
for (int j = 0; j < colCount; j++) {
Cell cell = row.getCell(j);
data[i-1][j] = getCellValue(cell);
}
}
workbook.close();
return data;
} catch (Exception e) {
throw new RuntimeException("Excel read failed", e);
}
}
}
// DataProvider using Excel:
@DataProvider(name = "excelData")
public Object[][] getExcelData() {
return ExcelUtils.readExcelData(
"src/test/resources/testdata.xlsx", "LoginData"
);
}
@Test(dataProvider = "excelData")
public void testLogin(String email, String password) {
// Test code using Excel data
}
DataProvider and parallel execution are where TestNG interviews separate manual testers from automation engineers.
Parallel Execution
Q8: How do you run tests in parallel?
// Parallel execution in testng.xml:
<!-- Parallel by methods (each method in separate thread) -->
<suite name="Suite" parallel="methods" thread-count="3">
<test name="All Tests">
<classes>
<class name="com.project.tests.LoginTest"/>
<class name="com.project.tests.CartTest"/>
</classes>
</test>
</suite>
<!-- Parallel by classes (each class in separate thread) -->
<suite name="Suite" parallel="classes" thread-count="4">
...
</suite>
<!-- Parallel by tests (each <test> tag in separate thread) -->
<suite name="Suite" parallel="tests" thread-count="2">
<test name="Chrome Tests">
<parameter name="browser" value="chrome"/>
<classes>
<class name="com.project.tests.LoginTest"/>
</classes>
</test>
<test name="Firefox Tests">
<parameter name="browser" value="firefox"/>
<classes>
<class name="com.project.tests.LoginTest"/>
</classes>
</test>
</suite>
<!-- Parallel by instances -->
<suite name="Suite" parallel="instances" thread-count="3">
...
</suite>
// IMPORTANT: For parallel execution, use ThreadLocal
// for WebDriver to avoid thread-safety issues:
private static ThreadLocal<WebDriver> driver =
new ThreadLocal<>();
public static WebDriver getDriver() {
return driver.get();
}
public static void setDriver(WebDriver d) {
driver.set(d);
}Q9: What are TestNG Listeners? Implement ITestListener.
// Listeners = interfaces that listen to test events
// Used for: custom reporting, screenshots, logging
// Common listeners:
// ITestListener → test method events
// ISuiteListener → suite start/finish
// IReporter → custom report generation
// IRetryAnalyzer → retry failed tests
// ITestListener implementation:
public class TestListener implements ITestListener {
@Override
public void onTestStart(ITestResult result) {
System.out.println("STARTED: " +
result.getMethod().getMethodName());
}
@Override
public void onTestSuccess(ITestResult result) {
System.out.println("PASSED: " +
result.getMethod().getMethodName());
}
@Override
public void onTestFailure(ITestResult result) {
System.out.println("FAILED: " +
result.getMethod().getMethodName());
// Take screenshot on failure
String screenshotPath = captureScreenshot(
result.getMethod().getMethodName());
System.out.println("Screenshot: " + screenshotPath);
}
@Override
public void onTestSkipped(ITestResult result) {
System.out.println("SKIPPED: " +
result.getMethod().getMethodName());
}
}
// Register listener in testng.xml:
<listeners>
<listener class-name="com.project.listeners.TestListener"/>
</listeners>
// Or using annotation:
@Listeners(TestListener.class)
public class LoginTest { ... }Q10: TestNG vs JUnit — When to use which?
This is a common comparison question in interviews. Here is the breakdown:
| Feature | TestNG | JUnit 5 |
|---|---|---|
| Parallel execution | Built-in (XML config) | Via JUnit Platform |
| Data-driven | @DataProvider | @ParameterizedTest |
| Grouping | @Test(groups) | @Tag |
| Dependencies | dependsOnMethods | @Order |
| Listeners | ITestListener, etc. | TestExecutionListener |
| XML config | testng.xml (powerful) | No equivalent |
| Retry failed | IRetryAnalyzer | @RepeatedTest |
| Best for | Selenium, E2E testing | Unit testing, Spring |
Rule of thumb: Use TestNG for Selenium/E2E automation (better parallel, grouping, XML control). Use JUnit for unit testing and Spring Boot projects (better IDE integration, Spring support).
How to Prepare
TestNG Interview — Priority by Experience
0–1 Years
- • Annotations & execution order
- • Basic testng.xml
- • Priority & enabled
- • Assert methods
- • TestNG vs JUnit basics
2–4 Years
- • @DataProvider patterns
- • Parallel execution setup
- • ITestListener implementation
- • Groups & dependencies
- • Excel data integration
5+ Years
- • Custom reporters & IReporter
- • Retry logic (IRetryAnalyzer)
- • Framework design with TestNG
- • CI/CD integration (Jenkins)
- • Thread-safe parallel design