What is TestNG?

Java testing framework inspired by JUnit/NUnit but designed for end-to-end, integration, and UI tests.

What is TestNG?

TestNG is an open-source Java testing framework created by Cédric Beust in 2004 to address gaps in JUnit 3 (which was the dominant Java test framework at the time). The name stands for "Test Next Generation". TestNG was designed not just for unit tests but for the broader testing pyramid: integration tests, end-to-end tests, UI tests with Selenium, and performance tests. While JUnit has caught up considerably with JUnit 5 (Jupiter), TestNG remains the dominant choice for Selenium-based UI testing and large enterprise Java test suites.

If your team is doing functional QA on Java applications — especially with Selenium WebDriver, REST Assured, or similar tools — there's a high chance you're using TestNG. The combination of TestNG + Selenium + Maven + Jenkins remains the canonical Java QA stack at most enterprises.

What TestNG offers that JUnit didn't (originally)

The original differentiators (some now matched by JUnit 5):

  • Annotation-driven configuration@Test, @BeforeMethod, @AfterClass, @DataProvider, @Listeners instead of subclassing TestCase.
  • Test groups — tag tests with @Test(groups = {"smoke", "regression"}) and run subsets via XML configuration. Foundational for layered test suites.
  • Dependent tests@Test(dependsOnMethods = "login") declares execution order. Controversial (unit tests should be independent) but useful for end-to-end flows.
  • Data providers — parameterized tests with @DataProvider. Run the same test method with N different inputs.
  • Parallel execution — at multiple granularities (suite, test, class, method) configured in testng.xml. The killer feature for slow Selenium suites.
  • XML test configuration — define test suites declaratively in XML. Run different combinations of tests without recompiling.
  • Listeners and reporters — extension points for custom logging, screenshots on failure (Selenium), and custom HTML reports.

The canonical TestNG test class

import org.testng.annotations.*;
import static org.testng.Assert.*;

public class CalculatorTest {
    private Calculator calc;

    @BeforeMethod
    public void setUp() {
        calc = new Calculator();
    }

    @Test(groups = {"smoke"})
    public void shouldAddTwoNumbers() {
        assertEquals(calc.add(2, 3), 5);
    }

    @Test(dataProvider = "divisionData")
    public void shouldDivide(int a, int b, int expected) {
        assertEquals(calc.divide(a, b), expected);
    }

    @DataProvider
    public Object[][] divisionData() {
        return new Object[][] {
            {10, 2, 5},
            {20, 4, 5},
            {100, 10, 10}
        };
    }
}

TestNG vs. JUnit 5 (the honest 2026 comparison)

FeatureTestNGJUnit 5
AnnotationsMature, comprehensiveMature in Jupiter
Parallel executionBuilt-in, easy configAvailable, more setup
Parameterized tests@DataProvider@ParameterizedTest
Test groups/tags@Test(groups=...)@Tag
Dependent testsYesNo (by design)
XML suite configtestng.xmlNone native
Selenium ecosystemDominant choiceIncreasing adoption
Spring/REST AssuredExcellent integrationExcellent integration
Modern Java (records, sealed)CompatibleCompatible

The pragmatic call: JUnit 5 for unit tests, TestNG for end-to-end and Selenium. Mixing both in one project is fine.

TestNG and Selenium WebDriver

The reason TestNG stays popular: Selenium UI tests are slow, flaky, and require careful orchestration. TestNG features that solve this:

  • Parallel browser execution. Run 10 Chrome instances in parallel against your test suite. Cuts wall-clock time dramatically.
  • Retry analyzers. Implement IRetryAnalyzer to automatically retry failed tests N times. Tames flakiness in Selenium.
  • Listeners for screenshots. Implement ITestListener.onTestFailure to capture a screenshot whenever any test fails — useful for debugging UI flakes.
  • Group-based runs. Run smoke tests on every commit, full regression nightly, all controlled via testng.xml.
  • BeforeSuite browser setup. Open WebDriver once per suite (not per test) to amortize browser startup cost.

Common TestNG pitfalls

  • Inter-test dependencies via shared state. Tests that pass when run alone but fail in a suite usually share static fields. Each test should be independent.
  • Parallel execution race conditions. WebDriver instances per thread, not per class. Use ThreadLocal<WebDriver> or Selenium's SeleniumGrid.
  • Hardcoded waits. Thread.sleep(5000) kills test speed. Use Selenium's WebDriverWait with explicit conditions.
  • testng.xml drift. XML configuration grows unwieldy. Keep it simple: define groups, point at packages, let TestNG discover tests.
  • Over-using dependsOnMethods. Long dependency chains create cascading failures. One failure cancels 10 downstream tests, hiding the original signal.
  • No retry budget. Retrying flaky tests forever masks real bugs. Cap retries at 2-3 and investigate anything that retries consistently.

Running TestNG: from CLI to CI

  • Maven Surefire/Failsafe — standard for TestNG in Maven projects. mvn test runs unit tests; mvn verify runs integration tests via Failsafe.
  • GradleuseTestNG() in test config; otherwise standard.
  • IntelliJ IDEA / Eclipse — first-class TestNG support; right-click any test → Run.
  • CI (Jenkins, GitHub Actions, GitLab) — invoke via Maven/Gradle, archive testng-results.xml + custom HTML reports.
  • Docker — common pattern for Selenium: Selenoid or Selenium Grid in Docker, TestNG runs in CI hitting the grid.

FAQ: TestNG

Should I use TestNG or JUnit 5 for new projects?

For unit tests in greenfield projects, JUnit 5 — it's the default in Spring Boot and most modern Java tooling. For Selenium-heavy QA suites, TestNG — better parallel execution and ecosystem fit. Many projects use both.

Is TestNG still actively maintained?

Yes. TestNG had a major 7.x release line (current as of 2026); active maintenance and Java 21+ compatibility. Cédric Beust still champions it.

Can TestNG run JUnit tests?

Yes. TestNG can wrap JUnit tests via junit="true" in testng.xml. Useful during gradual migrations. JUnit 5 cannot directly run TestNG tests.

How do I run TestNG tests in parallel?

In testng.xml: <suite parallel="methods" thread-count="4">. Granularities: suite, tests, classes, methods, instances. Methods is most fine-grained but requires fully independent tests.

What's a TestNG "group"?

A tag on a test method. @Test(groups = {"smoke", "regression"}). Run via testng.xml: <groups><run><include name="smoke"/></run></groups>. Letting you split test suites into smoke (fast) and regression (slow) without separate test classes.

What about TestNG with Spring Boot?

Use spring-test with TestNG via @ContextConfiguration + AbstractTestNGSpringContextTests. Spring Boot defaults to JUnit 5; you can switch to TestNG by replacing dependencies. Spring's docs cover both.

How LoadFocus relates to TestNG and Java load testing

TestNG covers functional Java testing; for load testing the same Java applications, JMeter is the canonical tool. LoadFocus JMeter cloud testing runs your existing .jmx files at scale across 25+ regions without you managing JMeter infrastructure. Use TestNG for functional regression, JMeter for capacity validation, and API monitoring for production observability.

How fast is your website?

Elevate its speed and SEO seamlessly with our Free Speed Test.

Free Website Speed Test

Analyze your website's load speed and improve its performance with our free page speed checker.

×