TestNG Tutorial
โก Smart Summary
TestNG is a Next-Generation Java testing framework that pairs with Selenium for structured automation, rich reporting, and parallel execution. This tutorial covers the core annotations, project setup in Eclipse, writing the first test case, HTML reports, and advanced parameter usage.

What is TestNG?
TestNG is an automation testing framework where “NG” stands for “Next Generation”. TestNG is inspired by JUnit and uses Java annotations (@) to control test flow. It overcomes JUnit’s earlier limitations and is designed to make end-to-end testing easier.
With TestNG you can generate a proper report and immediately see how many tests passed, failed, or were skipped. You can also re-run only the failed cases.
For example:
- Suppose you have five test cases, each in its own method, written without TestNG. Three pass; the fourth fails. After fixing the fourth, you want to re-run only that one, since the first three already passed. This is hard to do with plain main()-method code.
- TestNG provides a
testng-failed.xmlfile in thetest-outputfolder. Running that XML re-executes only the failed cases.
Beyond that, you will learn the advantages of TestNG, how to write test methods with @Test annotations, and how to convert your classes into a test suite that runs from Eclipse or the command line.
Why Use TestNG with Selenium?
By default, Selenium tests do not produce nicely formatted results. With TestNG plugged in, the test runner emits a structured report you can share with the team.
Most Selenium users prefer TestNG over JUnit because of its broader feature set. The key features for Selenium are:
- Reports that include the number of test cases run, passed, failed, and skipped.
- Easy grouping of test cases via a
testng.xmlfile, with execution priorities. - Repeat a test multiple times without loops using
invocationCount. - Run multiple tests on multiple browsers โ cross-browser testing support.
- Smooth integration with Maven, Jenkins, and other CI tooling.
- Readable annotations โ for example, @BeforeMethod, @AfterMethod, @BeforeTest, @AfterTest.
- Selenium WebDriver has no native reporting; TestNG fills that gap with a clean HTML report like the one below.
- TestNG simplifies test code. You no longer need a static main method; annotations decide what runs and when.
- Uncaught exceptions are handled gracefully by TestNG. They are reported as failed steps without terminating the entire run.
Advantages of TestNG over JUnit
TestNG offers three major advantages over JUnit:
- Annotations are easier to understand and use.
- Test cases can be grouped and prioritised with less effort.
- Parallel test execution is supported out of the box.
What is an Annotation in TestNG?
Annotations in TestNG are lines of code placed above a method to control how it is executed. They always start with the @ symbol. A simple example is shown below.
Annotations are covered in detail in the section “Annotations Used in TestNG” later in this tutorial, so the example above is just to set expectations. TestNG annotations are easier to code and read than the JUnit equivalents, and they are essential when running tests on Selenium Grid where parallel execution matters.
How to Write Test Cases in TestNG
Writing a TestNG test case takes three steps:
- Write your business logic and place TestNG annotations above each method.
- Add metadata such as class name, group name, and package name.
- Run the TestNG class from your IDE or the command line.
Create a Test Case Using TestNG Annotations
Now we will create our first test case using TestNG annotations in Selenium. Before writing the test, set up a new TestNG project in Eclipse and call it FirstTestNGProject.
Setting Up a New TestNG Project
Step 1) Click File > New > Java Project.
Step 2) Enter FirstTestNGProject as the project name and click Next.
Step 3) Import the TestNG libraries. Click the Libraries tab and then Add Libraryโฆ.
Step 4) In the Add Library dialog, choose TestNG and click Next.
Step 5) Click Finish.
TestNG should now appear in the Libraries list.
Step 6) Add the JAR files that contain the Selenium API. These come from the Java client driver downloaded from selenium.dev/downloads.
Navigate to the folder where the Selenium JARs are stored.
After adding the external JARs, the screen should look like this.
Step 7) Click Finish. The new FirstTestNGProject appears in the Package Explorer.
How to Create a New TestNG Test File
With the project ready, create a new TestNG file.
Step 1) Right-click the src folder and choose New > Otherโฆ.
Step 2) Expand the TestNG folder, select TestNG class, and click Next.
Step 3) Enter the values shown below and click Finish. The Java file is named FirstTestNGFile.
Step 4) Eclipse generates the TestNG template shown below.
Coding Your First TestNG Test Case
Create the first test case that verifies the title of the Mercury Tours homepage.
package firsttestngpackage;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.Test;
public class FirstTestNGFile {
public String baseUrl = "https://demo.guru99.com/test/newtours/";
public WebDriver driver;
@Test
public void verifyHomepageTitle() {
System.out.println("launching firefox browser");
// Selenium 4 ships Selenium Manager, so the driver path is no longer required.
driver = new FirefoxDriver();
driver.get(baseUrl);
String expectedTitle = "Welcome: Mercury Tours";
String actualTitle = driver.getTitle();
Assert.assertEquals(actualTitle, expectedTitle);
driver.quit();
}
}
Things to notice:
- TestNG does not need a
main()method. - Methods do not need to be static.
- The @Test annotation marks
verifyHomepageTitle()as a test case. - Annotations live in the
org.testng.annotations.*package. - The Assert class from
org.testng.Assertdrives verifications.
You may have multiple @Test annotations in a single TestNG file. We cover that in the “Annotations Used in TestNG” section.
Running the Test
Right-click the file and run it as a TestNG test. Eclipse produces two outputs โ a text result in the Console window and a graphical result in the TestNG Results window.
Checking Reports Created by TestNG
The Console window provides a text-based summary while the TestNG Results window shows a graphical view.
Generating HTML Reports
TestNG can also generate full HTML reports.
Step 1) After running FirstTestNGFile, right-click the project and choose Refresh.
Step 2) A test-output folder appears. Expand it and locate index.html โ the HTML report for the most recent run.
Step 3) Double-click index.html to open it inside Eclipse’s browser. Press F5 to refresh after future runs.
Annotations Used in TestNG
You have already seen the @Test annotation. The rest of this section covers the most useful advanced annotations.
Multiple Test Cases
A single TestNG file can hold multiple @Test annotations. By default, methods annotated with @Test execute in alphabetical order. In the code below, methods c_test, a_test, and b_test run alphabetically regardless of source order.
Run the code and open index.html. Click Chronological view.
Parameters
To override default ordering, use the priority parameter. Parameters are keywords that modify an annotation’s behaviour.
- Assign a value with
=. - Wrap parameters in parentheses placed immediately after the annotation, as shown below.
TestNG executes @Test annotations from the lowest priority value to the highest. The priority numbers do not need to be consecutive.
The HTML report confirms that methods executed in ascending priority order.
Multiple Parameters
Besides priority, @Test accepts the alwaysRun parameter (true or false). To use two or more parameters in a single annotation, separate them with a comma:
@Test(priority = 0, alwaysRun = true)
@BeforeTest and @AfterTest
| @BeforeTest | Methods under this annotation run before the first test case in the TestNG file. |
| @AfterTest | Methods under this annotation run after all test cases in the TestNG file finish. |
Consider the code below.
package firsttestngpackage;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.*;
public class FirstTestNGFile {
public String baseUrl = "https://demo.guru99.com/test/newtours/";
public WebDriver driver;
@BeforeTest
public void launchBrowser() {
System.out.println("launching firefox browser");
driver = new FirefoxDriver();
driver.get(baseUrl);
}
@Test
public void verifyHomepageTitle() {
String expectedTitle = "Welcome: Mercury Tours";
String actualTitle = driver.getTitle();
Assert.assertEquals(actualTitle, expectedTitle);
}
@AfterTest
public void terminateBrowser() {
driver.quit();
}
}
From the table and code, we can predict that the sequence will be:
- 1st โ
launchBrowser() - 2nd โ
verifyHomepageTitle() - 3rd โ
terminateBrowser()
The placement of annotation blocks in the source file does not affect their execution order. Try reshuffling the methods as shown below.
package firsttestngpackage;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.*;
public class FirstTestNGFile {
public String baseUrl = "https://demo.guru99.com/test/newtours/";
public WebDriver driver;
@AfterTest // Jumbled
public void terminateBrowser() {
driver.quit();
}
@BeforeTest // Jumbled
public void launchBrowser() {
System.out.println("launching firefox browser");
driver = new FirefoxDriver();
driver.get(baseUrl);
}
@Test // Jumbled
public void verifyHomepageTitle() {
String expectedTitle = "Welcome: Mercury Tours";
String actualTitle = driver.getTitle();
Assert.assertEquals(actualTitle, expectedTitle);
}
}
Run the code and verify the result.
@BeforeMethod and @AfterMethod
| @BeforeMethod | Methods under this annotation run before each test method. |
| @AfterMethod | Methods under this annotation run after each test method. |
In Mercury Tours, suppose we want to verify the titles of two target pages reached from the homepage.
The flow of the test is:
- Open the homepage and verify its title.
- Click REGISTER and verify the title of its target page.
- Go back to the homepage and verify the title.
- Click SUPPORT and verify the title of its target page.
- Go back to the homepage and verify the title again.
The code below shows how @BeforeMethod and @AfterMethod handle the repeated steps.
package firsttestngpackage;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.*;
public class FirstTestNGFile {
public String baseUrl = "https://demo.guru99.com/test/newtours/";
public WebDriver driver;
public String expected = null;
public String actual = null;
@BeforeTest
public void launchBrowser() {
System.out.println("launching firefox browser");
driver = new FirefoxDriver();
driver.get(baseUrl);
}
@BeforeMethod
public void verifyHomepageTitle() {
String expectedTitle = "Welcome: Mercury Tours";
String actualTitle = driver.getTitle();
Assert.assertEquals(actualTitle, expectedTitle);
}
@Test(priority = 0)
public void register() {
driver.findElement(By.linkText("REGISTER")).click();
expected = "Register: Mercury Tours";
actual = driver.getTitle();
Assert.assertEquals(actual, expected);
}
@Test(priority = 1)
public void support() {
driver.findElement(By.linkText("SUPPORT")).click();
expected = "Under Construction: Mercury Tours";
actual = driver.getTitle();
Assert.assertEquals(actual, expected);
}
@AfterMethod
public void goBackToHomepage() {
driver.findElement(By.linkText("Home")).click();
}
@AfterTest
public void terminateBrowser() {
driver.quit();
}
}
After running the test, TestNG reports the sequence below.
In short: place setup steps inside @BeforeMethod and cleanup or navigation reset inside @AfterMethod so each test case starts and ends in a known state.
Summary of TestNG Annotations
- @BeforeSuite: runs before all tests in the suite.
- @AfterSuite: runs after all tests in the suite.
- @BeforeTest: runs before any test method belonging to the classes inside a <test> tag.
- @AfterTest: runs after all test methods belonging to the classes inside a <test> tag.
- @BeforeGroups: runs shortly before the first test method that belongs to any listed group.
- @AfterGroups: runs shortly after the last test method that belongs to any listed group.
- @BeforeClass: runs before the first test method in the current class.
- @AfterClass: runs after all test methods in the current class.
- @BeforeMethod: runs before each test method.
- @AfterMethod: runs after each test method.
- @Test: marks the method as a test case.

































