Next-Gen App & Browser Testing Cloud
Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

TestNG is an open-source Java test framework, and one detail trips up newcomers: a TestNG class has no main() method of its own. A runner has to discover your annotated @Test methods and invoke them for you. That runner can be one of seven things, which gives you seven common ways to invoke (run) TestNG:
testng.xml suite file (Run As > TestNG Suite).java -cp ... org.testng.TestNG testng.xml.maven-surefire-plugin.useTestNG() in the test task.new TestNG(), run()).Each method below includes a working example for TestNG 7.x on Java 17. The examples assume the current org.testng:testng line; jcommander is already bundled inside modern TestNG JARs, so older advice about adding it separately no longer applies.
The fastest way to run a test while you are writing it is straight from the editor. With the TestNG plugin installed, right-click a class, a single method, or a testng.xml file and choose Run As > TestNG Test (or TestNG Suite). The plugin ships bundled with IntelliJ IDEA; in Eclipse you install it once from the Eclipse Marketplace.
What you need to know to invoke TestNG from an IDE:
A minimal class the IDE can invoke directly looks like this:
import org.testng.Assert;
import org.testng.annotations.Test;
public class LoginTest {
@Test
public void validCredentialsShouldLogIn() {
boolean isLoggedIn = login("[email protected]", "Secret123");
Assert.assertTrue(isLoggedIn, "User should be logged in");
}
private boolean login(String user, String pass) {
// ... call your app or page object here ...
return user != null && pass != null;
}
}A testng.xml file is the declarative definition of a suite. It lists the tests, classes, packages, groups, parameters, and parallel settings that make up a run, so you can describe a whole regression pass once and invoke it consistently from any environment. If you want the full background on what a suite is, see What Is Test Suite in TestNG?.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="RegressionSuite" verbose="1">
<test name="LoginTests">
<classes>
<class name="com.example.tests.LoginTest"/>
<class name="com.example.tests.CheckoutTest"/>
</classes>
</test>
</suite>With the file in place, you can invoke the suite in two quick ways:
testng.xml and choose Run As > TestNG Suite.The most direct way to run TestNG, with no IDE and no build tool, is the org.testng.TestNG launcher. Put the TestNG JAR and your compiled classes on the classpath, then hand it a suite file or a class. This is also the route to understand first because every other method ultimately drives this same launcher under the hood.
# Run a whole suite (testng.jar + your compiled classes on the classpath)
java -cp "out/classes:libs/*" org.testng.TestNG testng.xml
# Run several suites at once
java -cp "out/classes:libs/*" org.testng.TestNG suite1.xml suite2.xml
# Run a single class, no suite file needed
java -cp "out/classes:libs/*" org.testng.TestNG -testclass com.example.tests.LoginTest
# Run only specific groups
java -cp "out/classes:libs/*" org.testng.TestNG -groups smoke testng.xmlA couple of points worth keeping in mind for command-line runs:
;) on Windows.-testclass, -methods, and -groups to execute exactly the slice you care about.For a deeper walkthrough of flags and Windows-specific quirks, see How to Run TestNG Using the Command Prompt?.
In most real projects, Maven invokes TestNG. You declare the testng dependency, point the maven-surefire-plugin at your suite file, and the plugin runs the suite during the test phase. Surefire auto-detects TestNG from the dependency, so no extra provider configuration is needed.
<!-- pom.xml -->
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>With that wired up, a few commands cover most needs:
# Run the suite configured above
mvn test
# Override the suite file at runtime
mvn test -DsuiteXmlFile=src/test/resources/smoke.xml
# Run a single test class
mvn test -Dtest=LoginTestGradle defaults to JUnit, so you have to tell the test task to use TestNG explicitly. Add the dependency, call useTestNG() inside the test block, and optionally point it at a suite file. Running gradle test then invokes the suite.
// build.gradle
dependencies {
testImplementation 'org.testng:testng:7.10.2'
}
test {
useTestNG() {
suites 'src/test/resources/testng.xml' // optional: point at a suite
}
testLogging {
events "passed", "skipped", "failed"
}
}gradle test
# or, with the wrapper
./gradlew testA common misconception is that a CI server runs TestNG. It does not. Jenkins, GitHub Actions, GitLab CI, and the rest simply invoke your build tool, and the build tool invokes TestNG. So a CI pipeline is really just mvn test or gradle test wrapped in a checkout and a Java setup step.
A GitHub Actions workflow that checks out the repo, sets up Java 17, and runs the suite:
# .github/workflows/tests.yml
name: TestNG CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
- name: Run TestNG suite
run: mvn -B testIn Jenkins, an Execute shell build step (or a Maven build step) does exactly the same thing:
# Jenkins "Execute shell" build step
mvn -B testWhen you need full control, instantiate the framework yourself with the TestNG API. This is how you build custom test runners, generate suites dynamically at runtime, or embed test execution inside a larger application. You either hand TestNG a list of classes or build an XmlSuite in code, then call run().
import org.testng.TestNG;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;
import java.util.Collections;
public class ProgrammaticRunner {
public static void main(String[] args) {
// Option A: run classes directly
TestNG testng = new TestNG();
testng.setTestClasses(new Class[]{ LoginTest.class, CheckoutTest.class });
testng.run();
// Option B: build and run an XML suite in code
XmlSuite suite = new XmlSuite();
suite.setName("ProgrammaticSuite");
XmlTest test = new XmlTest(suite);
test.setName("SmokeTest");
// test.setXmlClasses(List.of(new XmlClass("com.example.tests.LoginTest")));
TestNG suiteRunner = new TestNG();
suiteRunner.setXmlSuites(Collections.singletonList(suite));
suiteRunner.run();
}
}All seven methods end up driving the same TestNG engine; they differ in how much setup they need and where they fit in your workflow. Use this comparison to pick the right one.
| Method | Best for | Trade-off |
|---|---|---|
| IDE (Eclipse / IntelliJ) | Writing and debugging a single test fast | Manual, not repeatable in automation |
| testng.xml suite | Defining a stable, shareable run | Still needs a runner to execute it |
| Command line | Quick runs with no build tool | You manage the classpath by hand |
| Maven (surefire) | Standard project builds and CI | Requires a configured pom.xml |
| Gradle (useTestNG()) | Gradle-based project builds | Must opt out of the JUnit default |
| CI server | Automated runs on every push | Only invokes your build tool |
| Programmatic API | Custom runners, dynamic suites | Most code and maintenance |
Whichever method invokes your suite, the same testng.xml with parallel="tests" and a thread-count can target a remote Selenium Grid instead of a single local browser. That lets one run fan out across many browser and OS combinations at once. To run your TestNG suites in parallel on the cloud, point your driver at TestMu AI Selenium Automation and execute the same suite you already run locally, with no change to your test code.
Yes. TestNG classes do not declare a public static void main method. Instead a runner, whether an IDE plugin, a build tool, the org.testng.TestNG launcher, or the TestNG API, discovers your @Test methods through their annotations and invokes them for you.
The command line is the most direct route. With the TestNG JAR and your compiled classes on the classpath, run java -cp "..." org.testng.TestNG testng.xml and TestNG executes the suite without any build tool or IDE involved.
On the command line, list each file after the launcher, for example org.testng.TestNG suite1.xml suite2.xml. With Maven, add multiple <suiteXmlFile> entries inside the surefire <suiteXmlFiles> block. Both approaches run all of the listed suites in a single execution.
Skip the suite file and pass the class directly with the -testclass flag, for example org.testng.TestNG -testclass com.example.tests.LoginTest. You can narrow execution further with -methods or restrict it to specific -groups.
They are not alternatives. The testng.xml file defines which tests, classes, and groups make up a suite, while Maven runs that suite through the maven-surefire-plugin. In a typical project you use both together: the XML describes the suite and mvn test executes it.
A CI server does not run TestNG directly. It invokes your build tool, so a Jenkins or GitHub Actions job simply calls mvn test or gradle test, and that build step launches the TestNG suite exactly as it would on your machine.
KaneAI - Testing Assistant
World’s first AI-Native E2E testing agent.

TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance