Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To set up TestNG with Selenium, add compatible Selenium Java and TestNG dependencies to your Maven or Gradle project, create a test class with TestNG annotations, start and quit WebDriver in lifecycle methods, run the tests through your build tool, and add testng.xml when you need explicit suites, groups, parameters, or parallel execution.

This guide uses Java. TestNG provides annotations, data-driven tests, groups, parameters, and configurable execution. Selenium still requires a browser and a compatible driver in addition to the Java library.

Prerequisites and compatibility checks

  • A supported Java Development Kit and a project that already uses Maven or Gradle.
  • Selenium Java bindings and TestNG dependencies.
  • A locally installed browser and the corresponding WebDriver support. Selenium’s getting-started guidance treats the language bindings, browser, and driver as separate prerequisites.
  • A test source directory such as src/test/java.

Do not copy a version number blindly from an old tutorial. TestNG documentation examples show 7.9.0, but that is not a guarantee that it is the newest release or compatible with every JDK, Selenium, browser, or build-plugin combination. Select versions that your project and CI environment support, then verify the current requirements in the official TestNG and Selenium documentation before pinning them.

Add Selenium and TestNG dependencies

Maven

Selenium installation for Java is normally performed with a build tool. In pom.xml, declare the Selenium Java library and TestNG in test scope. Keep the version properties as values you have verified for your project rather than treating the placeholders below as releases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<properties>
  <selenium.version>YOUR_VERIFIED_SELENIUM_VERSION</selenium.version>
  <testng.version>YOUR_VERIFIED_TESTNG_VERSION</testng.version>
</properties>

<dependencies>
  <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>${selenium.version}</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>${testng.version}</version>
    <scope>test</scope>
  </dependency>
</dependencies>

Maven Surefire is the component that discovers and runs tests during the Maven test phase. Use the current Surefire documentation and your project’s existing plugin configuration; an archived plugin example should not be copied as current version advice.

Gradle

Use the Gradle configuration already established by your codebase and add the same two libraries to the test dependencies. TestNG documents Gradle dependency setup and Gradle’s Test task provides TestNG execution support.

dependencies {
    testImplementation("org.seleniumhq.selenium:selenium-java:YOUR_VERIFIED_SELENIUM_VERSION")
    testImplementation("org.testng:testng:YOUR_VERIFIED_TESTNG_VERSION")
}

tasks.test {
    useTestNG()
}

Check the selected Gradle, Java, Selenium, TestNG, and browser-driver compatibility together. A dependency that resolves successfully can still fail at runtime if the browser or driver is incompatible.

Write a first Selenium TestNG class

TestNG runs methods marked with @Test; you do not add a TestNG-specific main method. Configuration annotations define setup and cleanup hooks. The following minimal example creates a browser for each test method and always attempts to close it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
package example;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class ExampleTest {
    private WebDriver driver;

    @BeforeMethod
    public void setUp() {
        driver = new ChromeDriver();
    }

    @Test
    public void pageHasExpectedTitle() {
        driver.get("https://example.com");
        Assert.assertEquals(driver.getTitle(), "Example Domain");
    }

    @AfterMethod(alwaysRun = true)
    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }
}

This is an illustration, so replace the URL and expected title with a page belonging to your application. The test will only work after dependencies, a browser, and driver discovery are correctly configured. Keeping the driver in an instance field lets each test method use the browser created by @BeforeMethod. The null check prevents cleanup from masking a setup failure.

Choose an appropriate lifecycle

  • @BeforeMethod/@AfterMethod gives every test a clean browser and is the safest default when tests change state.
  • @BeforeClass/@AfterClass can reduce startup overhead when several methods intentionally share one browser, but state leakage must then be controlled.
  • Use alwaysRun = true for teardown that must execute after a failure or skipped configuration method.

Use explicit waits instead of arbitrary sleeps

For real pages, wait for a meaningful condition (for example, an element to become visible or clickable) before asserting. A fixed sleep makes tests slower and still fails when a page needs longer than the chosen delay. Keep locators and test data isolated so later parallel execution does not create races.

Run the test through the build tool

Maven

  1. Place the class under src/test/java and ensure its package declaration matches its directory.
  2. From the project root, run mvn test. Maven compiles test sources and delegates execution to Surefire.
  3. Read the first browser-driver or assertion error in the console; later stack-trace lines are often consequences rather than the cause.

If Surefire reports that no tests were found, confirm the class is in the test source directory, the method has @Test, the TestNG dependency is present, and the current Surefire configuration supports TestNG.

Gradle

  1. Keep the class under src/test/java.
  2. Ensure the test task contains useTestNG().
  3. Run ./gradlew test (or gradlew.bat test on Windows) and inspect the generated test report when a method fails.

Build-tool execution is enough for a small suite. An XML suite is an additional selection and configuration layer, not a prerequisite for every TestNG test.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Configure a testng.xml suite

TestNG represents a suite in one XML file. Use it when you need a named collection of classes, packages, groups, or methods; suite parameters; or parallel execution settings.

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Browser suite">
  <test name="Smoke tests">
    <classes>
      <class name="example.ExampleTest"/>
    </classes>
  </test>
</suite>

Save it at the project root or another location your build configuration can address. The fully qualified class name must match the Java package. A suite can contain multiple <test> blocks and classes. You can also select groups or individual methods instead of listing every class.

Pass a parameter

Declare a value in XML and receive it with TestNG’s parameter annotation:

<suite name="Environment suite">
  <parameter name="baseUrl" value="https://example.com"/>
  <test name="Smoke">
    <classes>
      <class name="example.ExampleTest"/>
    </classes>
  </test>
</suite>
import org.testng.annotations.Parameters;

@Parameters("baseUrl")
@Test
public void opensHomePage(String baseUrl) {
    driver.get(baseUrl);
}

Keep secrets out of XML committed to source control. Inject credentials through your CI secret mechanism and map them into test configuration instead.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Select groups

Mark a method with @Test(groups = "smoke"), then include or exclude that group in the suite. Groups let a smoke run and a longer regression run use the same test classes without editing Java source.

Sequential or parallel execution?

Sequential execution is the reliable starting point. TestNG can parallelize methods, classes, tests, instances, or suites with thread settings in XML. For example:

<suite name="Parallel browser suite" parallel="classes" thread-count="2">
  <test name="UI tests">
    <packages>
      <package name="example.ui"/>
    </packages>
  </test>
</suite>

Before enabling this, create one WebDriver instance per concurrently running test (never a single static driver), isolate users and test data, avoid mutable shared fields, and ensure the CI machine has enough browser resources. Parallel mode can shorten wall-clock time, but it exposes ordering assumptions and shared-state defects that sequential runs hide.

Maven, Gradle, suite XML: which setup should you choose?

Choice Use it when Trade-off
Maven The repository and CI already use Maven. Use existing Surefire conventions; do not mix in unrelated Gradle configuration.
Gradle The repository already uses Gradle. Keep the TestNG dependency and useTestNG() in the existing test task.
Build-tool discovery You have a small suite and standard test naming. Less configuration, but fewer explicit suite-level selections.
testng.xml You need groups, parameters, package/class selection, or parallel controls. An extra file must stay synchronized with renamed packages and classes.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common failures

ClassNotFoundException or missing TestNG annotations

Cause: TestNG is absent, has the wrong scope, or dependency resolution failed. Confirm the dependency appears in the test runtime classpath, refresh Maven or Gradle, and verify the selected version is compatible with the JDK.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“Unable to locate a driver” or browser startup failure

Cause: the browser is missing, the driver is unavailable, or browser and driver versions are incompatible. Install the intended browser, make the matching driver discoverable using your Selenium-supported setup, and check the CI machine rather than only your laptop.

Surefire or Gradle says no tests were executed

Confirm the source directory, class naming and @Test annotation. In Maven, inspect Surefire’s current TestNG integration; in Gradle, confirm useTestNG() is applied to the test task.

testng.xml cannot find a class

Use the fully qualified name, including package, and ensure the XML points to the compiled test source. A renamed package is a common cause.

Tests pass alone but fail together

Look for shared browser state, static variables, reused accounts, fixed ports, or test-data collisions. Reset state in lifecycle methods before considering parallel execution.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The browser remains open after a failure

Put cleanup in @AfterMethod(alwaysRun = true) (or the corresponding class-level hook) and guard against a null driver. Also check that the process is not being terminated externally by the CI runner.

Or skip the browser setup

If your goal is to obtain a page image rather than drive a browser in a test, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. AI agents can call its take_screenshot, get_page_info, and capture_pdf MCP tools.

One request returns PNG, JPEG, WebP, or PDF. The API supports full-page and CSS-selector captures, device presets or custom viewports, dark mode, retina scale, waits, custom CSS and JavaScript, clicks, hidden selectors, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, configurable caching, signed image links, asynchronous webhooks, bulk capture of up to 100 URLs per call, and a usage API.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for options and response headers. A free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

FAQ

Do I need testng.xml to run one test?

No. A correctly configured Maven or Gradle test task can discover and run an annotated TestNG class without an XML suite.

Can one TestNG project contain multiple browsers?

Yes. Parameterize the browser choice or use separate suite selections, while creating and quitting the appropriate WebDriver for each test scope.

Should WebDriver be static?

Usually no. Instance-scoped drivers avoid tests sharing a browser and are essential when classes or methods run concurrently.

Where should browser credentials be stored?

Keep secrets in environment or CI secret storage and pass non-secret configuration through parameters or system properties; do not commit passwords to Java or suite XML.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.