Skip to content
QA Knowledge Hub

TestNG interview questions

Updated 2026-11-13 · 11 min read

Thirty TestNG interview questions, from annotation scope to diagnosing parallel failures. Includes Java examples, suite XML and practical framework decisions.

A useful TestNG answer explains who creates the test data, when resources are released and what evidence survives a failure. Use a cart or login test to explain those choices rather than listing annotation names alone.

Basics and lifecycle

1. What does TestNG do in an automation framework?

TestNG discovers test methods, runs configuration methods, supplies data and records results. Selenium controls the browser; Rest Assured sends API requests; TestNG decides how those tests execute. For example, it can select a smoke group and report which login cases failed without knowing how login works.

2. How do you declare a test and an assertion?

Annotate a public method with org.testng.annotations.Test and use TestNG assertions. Here the values are paise: the check verifies arithmetic, not an actual ShopLite checkout.

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

public class TotalTest {
    @Test
    public void twoItemsHaveTheExpectedSubtotal() {
        int unitPrice = 14900;
        Assert.assertEquals(unitPrice * 2, 29800, "Subtotal in paise");
    }
}

Use a message that tells the reader which business expectation failed. Printing a wrong value without asserting it still produces a passing test.

3. What is the usual configuration annotation order?

For a simple class it is @BeforeSuite, @BeforeTest, @BeforeClass, @BeforeMethod, the test, then the corresponding after annotations in reverse scope order. @BeforeMethod runs for each test invocation; @BeforeClass runs around a class instance's tests. Think about resource lifetime: a fresh cart belongs near method scope, while an immutable configuration can live longer.

4. Does @BeforeTest mean before every test method?

No: it refers to a test element in suite XML, which can contain several classes. For a fresh browser per method, use @BeforeMethod. Confusing those scopes can leave several methods sharing one browser and make the second test inherit the first test's login state.

Likely follow-up: When might @BeforeClass be suitable? For expensive read-only setup shared safely by that class, provided each method still isolates its mutable data.

5. How do you make cleanup run after failures?

Use @AfterMethod(alwaysRun = true) and make cleanup tolerate partially completed setup. If browser construction failed, closing a null reference adds a misleading second failure. Preserve the original error and release only resources the invocation actually acquired; the annotation cannot recover resources after the JVM is killed.

6. How does inheritance affect configuration methods?

TestNG runs inherited before configuration methods from the superclass toward the subclass, and after methods in the opposite direction. A base class can load configuration, while a subclass creates a feature-specific fixture. Avoid a deep inheritance chain: hidden setup makes it difficult to explain why a test has a particular account or token.

Selection and data

7. What are groups used for?

Groups label tests, for example @Test(groups = {"smoke", "api"}). A suite can include smoke tests and exclude destructive tests without moving classes. Choose groups that answer a real execution need; a label on every method is useful only if someone selects it.

8. What does priority guarantee?

Lower priorities are scheduled before higher ones; it is not a substitute for a business dependency or a safe parallel design. A login test with priority 1 should not prepare the account for a cart test with priority 2. Let each test arrange its own authenticated state so it can run alone.

9. What is dependsOnMethods, and what happens when the prerequisite fails?

A hard dependency declares that a method requires another method to succeed. A failed prerequisite normally causes the dependent method to be skipped, so distinguish a skip from an assertion failure in reports. It can model a deliberately linked workflow, but putting the whole regression behind one login method can hide useful failures.

10. How do XML parameters differ from data providers?

@Parameters binds named configuration values, such as a browser or base URL, from TestNG configuration. @DataProvider supplies multiple argument sets to a test method, such as accepted quantities and expected totals. Use the first for execution settings and the second for repeatable input cases; neither should carry committed secrets.

11. How do you provide an optional XML parameter?

Use TestNG's @Optional on the method parameter. The value is a fallback when the named parameter is absent, not validation that the supplied URL is safe.

import org.testng.annotations.BeforeClass;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;

public class EnvironmentSetup {
    protected String baseUrl;

    @BeforeClass
    @Parameters("baseUrl")
    public void configure(@Optional("http://localhost:3001") String url) {
        baseUrl = url;
    }
}

For destructive tests, separately reject an unapproved host before any requests are sent.

12. How do you write a small data-driven TestNG test?

The provider name connects to the test's dataProvider attribute. Each row must match the method's argument count and compatible types.

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

public class QuantityTest {
    @DataProvider(name = "quantities")
    public Object[][] quantities() {
        return new Object[][] {{1, 14900}, {2, 29800}, {3, 44700}};
    }

    @Test(dataProvider = "quantities")
    public void subtotalUsesQuantity(int quantity, int expected) {
        Assert.assertEquals(quantity * 14900, expected);
    }
}

In an API test, replace the multiplication under test with a call to the cart and assert its returned subtotal. Testing your own expected-value calculation alone does not validate the application.

13. How do you share a provider across classes?

Reference its class using dataProviderClass and its name using dataProvider. A public static provider is a straightforward choice for a separate utility class. Keep file parsing there, but keep assertions in the test; a malformed CSV should fail clearly during data loading rather than silently omit rows.

14. What does @Factory do differently from @DataProvider?

A factory creates test-class instances, often with different constructor data; a provider feeds arguments to test invocations. Use a provider for the same quantity check with several inputs. Consider a factory when each account type needs a class instance with several related tests, and make sure those tests still do not mutate each other's setup unexpectedly.

15. How do hard and soft assertions differ?

A hard assertion throws immediately when it fails. SoftAssert collects failures until assertAll() throws them together. Use hard assertions for prerequisites such as successful login; soft assertions can compare several independent profile fields. Create a fresh SoftAssert per invocation and always call assertAll(), or failures may never fail the test.

Suites, parallelism and retries

16. What belongs in testng.xml?

It selects suites, tests, classes, groups, parameters and execution settings. This example selects a class and passes a local URL; it assumes the class is in the qa package and available on the test classpath.

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="ShopLite smoke">
  <parameter name="baseUrl" value="http://localhost:3001"/>
  <test name="API smoke">
    <groups><run><include name="smoke"/></run></groups>
    <classes><class name="qa.ProductTest"/></classes>
  </test>
</suite>

Do not assume a successful run executed tests: a group filter can select nothing. Check the discovered test count.

17. What do the main parallel modes mean?

parallel="methods" schedules methods concurrently, classes separates classes, instances separates instances, and tests separates XML test elements. Set thread-count to cap the suite pool rather than assuming the machine can run unlimited browsers. Choose a mode that matches the isolation your fixtures actually provide.

18. How does data-provider parallelism work?

@DataProvider(parallel = true) permits its rows to execute concurrently. Provider execution has thread-pool settings distinct from ordinary suite scheduling; consult the version's pool options before estimating the total concurrency. Two rows using the same cart can still overwrite each other even if their Java arguments are different.

19. Why does a static WebDriver cause parallel failures?

All threads can overwrite the same reference: one test navigates while another quits that browser. Prefer invocation-owned resources; if using ThreadLocal, initialise on the executing thread, quit in teardown and call remove(). Thread-local storage isolates a reference, not server-side users, downloaded filenames or database rows.

Likely follow-up: Would a different browser per thread fix shared cart failures? No. Each thread also needs an independent user or cart.

20. How do you implement a bounded retry analyzer?

Implement IRetryAnalyzer.retry(ITestResult) and reference the class through @Test(retryAnalyzer = RetryOnce.class). This minimal stateful example illustrates the interface for a single non-parallel case; it needs an explicit per-invocation policy before reuse with data providers or parallel tests.

import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;

public class RetryOnce implements IRetryAnalyzer {
    private int retries;

    @Override
    public boolean retry(ITestResult result) {
        if (retries >= 1) return false;
        retries++;
        return true;
    }
}

A retry needs safe test setup and a retained first failure. Repeating a payment submission without an idempotency policy could create a second charge.

21. Is rerunning testng-failed.xml the same as retrying?

No. A generated failed-suite file lets you launch a later run focused on failures; a retry analyzer decides during execution whether to invoke a failed test again. Keep the original suite report when rerunning so a later pass does not erase evidence of instability. With Maven, use the report locations produced by your configured runner rather than assuming the IDE's paths.

22. How do timeOut and invocationCount help?

timeOut on @Test limits a test method's duration in milliseconds; invocationCount repeats it. Repetition can help expose unstable state, but it is not a realistic load model. For example, ten serial cart reads do not prove that checkout can handle concurrent users; use a load-testing tool for that question.

Listeners, reporting and Maven

23. What is a TestNG listener?

A listener receives lifecycle events without adding reporting code to every test. ITestListener can observe test failures; ISuiteListener observes suite events. Capture a failed test's screenshot while its browser still exists, and do not allow an attachment error to replace the original assertion error.

24. How do you register listeners?

Common choices are @Listeners on a class or a listeners element in XML. Use a single deliberate registration route to avoid duplicate attachments and confusing counts. Annotation transformers such as IAnnotationTransformer have special registration requirements: do not assume @Listeners can register every extension type.

25. How does IReporter differ from ITestListener?

ITestListener reacts to test events as execution progresses. IReporter receives results for report generation after suites finish. Use event callbacks to gather timely evidence, then reporting code to aggregate it; an end-of-run reporter cannot take a screenshot from a browser that was already closed.

26. Which reports should CI retain?

Keep machine-readable XML for CI test summaries and human-readable reports with failure details. Include test name, input case, environment, revision and sanitised evidence so an engineer can reproduce the failure. TestNG and Maven Surefire output locations depend on how they are invoked; archive the paths produced by the actual build, including on failure.

27. How do you run TestNG with Maven?

Add TestNG as a test-scoped dependency and use Maven Surefire for the test phase. Surefire can select a suite through its suiteXmlFiles configuration; then mvn test executes that selection. Pin compatible JDK, TestNG and plugin versions, and confirm that naming conventions or group filters have not produced a zero-test success.

28. Why does a test run in the IDE but not in Maven?

Compare the selected suite, class naming rules, groups, working directory, Java version and dependency classpath. An IDE run may directly select a method that Surefire does not discover by default. Inspect the Maven test summary first; no tests discovered and tests failing during setup require different fixes.

29. What do you check when tests pass alone but fail in a suite?

Look for shared account state, leftover cart items, mutable static fields and cleanup that did not run. Run the failing test after a suspected neighbour, then try a fresh user for each invocation. If only parallel runs fail, reduce concurrency to diagnose the race, but repair the isolation rather than permanently hiding it with serial execution.

30. How would you explain your TestNG framework in an interview?

Describe one concrete flow: a provider supplies quantities, setup creates an isolated user, an API client adds an item, assertions verify the cart, and teardown removes the data. Explain how groups select smoke tests and how CI retains failures. Name a tradeoff you actually made, such as fewer parallel browsers to stay within the test environment's capacity, rather than claiming the framework solves everything.

Practise it

Run ShopLite locally and design a TestNG data provider for quantities 1, 2 and 3. Verify returned cart totals, then explain how you would give each parallel invocation its own account. Use the Java questions to review the classes and interfaces involved.

Quick answers

Does TestNG automate the browser?

No. TestNG runs and reports tests; Selenium or another client performs browser actions.

Should every failure be retried?

No. Limit retries, preserve the first failure and investigate tests that pass only after retry.

Can a data provider run rows in parallel?

Yes, with parallel = true. Each invocation still needs isolated data and resources.

Sources

Want a project you can show in interviews?

The portfolio project kit walks you through testing a deliberately buggy app with Selenium or Playwright and API tests, then explaining it. The app itself is free.