Mastering TestNG for Effective Java Testing | Tutorial & Examples

Mastering TestNG for Effective Java Testing | Tutorial & Examples

TestNG Tutorial for Beginners: Complete Guide with Examples

Test automation is an essential part of modern software development. It helps developers and testers identify defects, verify application functionality, and maintain software quality as applications evolve. For Java-based testing, TestNG is a popular testing framework that provides tools for organizing, executing, and reporting automated tests.

Whether you are a beginner learning automation testing or an experienced tester working with Selenium WebDriver, understanding TestNG can help you build structured and maintainable test suites.

In this TestNG tutorial for beginners, you will learn what TestNG is, how to configure it using Maven, how to write your first test, and how to use annotations, assertions, DataProviders, test groups, and reports with practical Java examples.

What Is TestNG in Java?

TestNG stands for Testing Next Generation. It is an open-source testing framework for Java inspired by JUnit and NUnit. It provides features for organising test cases, managing test execution, supplying test data, and generating test reports.

TestNG is widely used in automation testing projects, particularly when combined with Selenium WebDriver for web application testing.

Unlike a basic Java program that simply executes instructions, a TestNG test uses annotations and framework configuration to identify test methods and manage their execution.

Why Is TestNG Used in Automation Testing?

TestNG helps testers organise automated tests and execute them according to defined requirements.

Its important capabilities include:

  • Annotation-based test configuration.
  • Grouping related test methods.
  • Running tests with multiple data sets.
  • Defining test dependencies.
  • Configuring parallel test execution.
  • Using listeners to customise test execution events.
  • Generating test execution reports.
  • Integrating with Maven, Selenium WebDriver, and continuous integration tools.

These features make TestNG useful for small testing projects as well as larger automation frameworks.

Who Should Learn TestNG?

TestNG is suitable for several groups of learners:

Java beginners: Developers who understand basic Java syntax can learn how to write and execute automated tests.

Manual testers: Testers interested in moving towards automation can use TestNG as part of a Java-based automation learning path.

Automation testers: Professionals can use its advanced features to manage larger test suites and improve test execution workflows.

Selenium learners: TestNG is commonly used to organise Selenium WebDriver tests, execute browser scenarios, and report test results.

A basic understanding of Java classes, methods, variables, and conditional statements is helpful before starting.

Key Features and Benefits of TestNG

Understanding TestNG’s features helps you decide how to structure an automation project.

1. Annotations

TestNG uses annotations such as @Test, @BeforeMethod, and @AfterMethod to identify test methods and configure setup and cleanup operations.

Annotations reduce the need to manage every testing step manually.

2. Data-Driven Testing

The @DataProvider annotation allows a test method to execute multiple times with different input data.

For example, a login test can check several username and password combinations without requiring a separate test method for every combination.

3. Test Groups

TestNG allows you to group test methods under names such as smoke, regression, or sanity.

You can then select particular groups when running tests, making it easier to execute a relevant subset of a large test suite.

4. Test Dependencies

You can configure one test method to depend on another using annotations such as dependsOnMethods.

This is useful when a test genuinely requires another operation to complete first. However, independent tests are generally easier to maintain and run in parallel.

5. Parallel Test Execution

TestNG supports parallel execution through its configuration options. This can help reduce execution time when tests are designed to run independently.

Parallel testing requires careful management of shared resources, browser instances, test data, and application state.

6. Listeners and Reporting

TestNG listeners allow you to respond to events such as test success, test failure, and test execution completion.

They can be used to add logging, capture screenshots when integrated with Selenium, or generate custom reports.

TestNG also produces standard test result files and HTML reports.

How to Set Up TestNG Using Java and Maven

Before writing your first TestNG test, configure a Java project with the necessary dependencies.

Prerequisites

Make sure you have the following:

  • A supported Java Development Kit (JDK).
  • An IDE such as Eclipse or IntelliJ IDEA.
  • Apache Maven for project and dependency management.
  • Basic knowledge of Java programming.

Maven downloads the required libraries and helps execute tests through a consistent build process.

Step 1: Create a Maven Project

Create a new Maven project in your preferred IDE.

A typical project structure looks like this:

TestNGProject/
├── pom.xml
└── src/
    ├── main/
    │   └── java/
    └── test/
        └── java/
            └── SimpleTest.java

The pom.xml file defines project dependencies and build configuration. Test classes are commonly placed under src/test/java.

Step 2: Add the TestNG Dependency

Open your pom.xml file and add the TestNG dependency inside the <dependencies> section.

<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>7.11.0</version>
    <scope>test</scope>
</dependency>

This example uses TestNG 7.11.0. Before using it in a new project, verify that the version is appropriate for your Java environment and project requirements.

After saving the file, allow Maven to download the dependency.

Step 3: Write Your First TestNG Test

Create a Java class named SimpleTest.java inside src/test/java.

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

public class SimpleTest {

    @Test
    public void testAddition() {
        int result = 2 + 2;

        Assert.assertEquals(result, 4);
    }
}

Here is how the code works:

  • @Test tells TestNG that the method is a test method.
  • testAddition() contains the logic being tested.
  • Assert.assertEquals() checks whether the actual result matches the expected result.
  • If the values match, the test passes. Otherwise, the test fails.

You do not need to extend a special TestNG class to create a normal test class.

Step 4: Execute the Test

You can run the test directly through your IDE by choosing the TestNG run option when available.

Alternatively, execute the following command from your Maven project’s root directory:

mvn test

Maven runs the tests configured for the project through its test execution plugins.

TestNG commonly generates an HTML report named index.html in the test-output directory when using its standard reporting configuration. Maven Surefire also produces test result files under target/surefire-reports.

Essential TestNG Annotations Explained

Annotations are among the most important concepts in TestNG. They tell the framework when to run particular methods and how to organise testing activities.

The @Test Annotation

The @Test annotation identifies a method that TestNG should execute as a test.

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

public class CalculatorTest {

    @Test
    public void testMultiplication() {
        int result = 5 * 4;

        Assert.assertEquals(result, 20);
    }
}

This test verifies that multiplying five by four produces twenty.

The @BeforeMethod and @AfterMethod Annotations

@BeforeMethod runs before each applicable test method, while @AfterMethod runs after each applicable test method.

These annotations are useful for preparing test data, resetting application state, or cleaning up resources.

import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class UserTest {

    @BeforeMethod
    public void setUp() {
        System.out.println("Preparing test data");
    }

    @Test
    public void testUserCreation() {
        System.out.println("Testing user creation");
    }

    @AfterMethod
    public void tearDown() {
        System.out.println("Cleaning up test data");
    }
}

For this test, setup runs before the test method and cleanup runs afterwards.

The @BeforeClass and @AfterClass Annotations

@BeforeClass runs once before the first test method in the current class, and @AfterClass runs once after the class’s test methods have finished.

These annotations are useful for class-level preparation and cleanup, such as setting up shared resources.

Other Useful TestNG Annotations

Annotation Purpose
@Test Marks a test method or test class.
@BeforeSuite Runs before the tests in a suite.
@AfterSuite Runs after the tests in a suite.
@BeforeTest Runs before the test methods associated with a <test> element in the suite XML.
@AfterTest Runs after those test methods.
@BeforeMethod Runs before each applicable test method.
@AfterMethod Runs after each applicable test method.
@BeforeClass Runs before the first test method in a class.
@AfterClass Runs after the class’s test methods.
@DataProvider Supplies data to a test method.
@Parameters Receives values configured through TestNG XML or supported parameter configuration.

Understanding these annotations helps you organise setup, test execution, and cleanup without repeating the same code unnecessarily.

Parameterized Testing Using TestNG DataProvider

Data-driven testing is useful when the same functionality must be verified against different inputs.

TestNG provides the @DataProvider annotation to supply multiple sets of data to a test method.

Example: Testing Addition With Multiple Inputs

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

public class DataProviderTest {

    @DataProvider(name = "additionData")
    public Object[][] provideData() {
        return new Object[][] {
            {1, 2, 3},
            {4, 5, 9},
            {10, 20, 30}
        };
    }

    @Test(dataProvider = "additionData")
    public void testAddition(
            int a, int b, int expected) {

        int result = a + b;

        Assert.assertEquals(result, expected);
    }
}

How This Example Works

The provideData() method returns three sets of test data.

Each row contains two input numbers and the expected result. TestNG passes each row to testAddition() and executes the method once for each data set.

This approach improves test coverage and reduces duplicated code.

DataProviders can also be useful for validating login scenarios, form inputs, calculations, API responses, and boundary conditions.

Organising TestNG Test Suites and Groups

As a project grows, running every test for every change can become inefficient. TestNG provides test groups and suite configuration to help manage test execution.

Using Test Groups

You can assign a test method to a group using the groups attribute of @Test.

import org.testng.annotations.Test;

public class ApplicationTests {

    @Test(groups = {"smoke"})
    public void testApplicationLaunch() {
        System.out.println("Application launch test");
    }

    @Test(groups = {"regression"})
    public void testUserProfile() {
        System.out.println("User profile test");
    }
}

Here, one test belongs to the smoke group, while the other belongs to the regression group.

Groups can be selected in TestNG XML configuration or through supported runner settings.

Creating a TestNG XML Suite

A testng.xml file lets you configure which test classes or groups should run.

<!DOCTYPE suite SYSTEM
    "https://testng.org/testng-1.0.dtd">

<suite name="ApplicationSuite">
    <test name="SmokeTests">
        <groups>
            <run>
                <include name="smoke"/>
            </run>
        </groups>

        <classes>
            <class name="ApplicationTests"/>
        </classes>
    </test>
</suite>

This configuration selects the smoke group from ApplicationTests.

Save the XML file in an appropriate project location and run it through the TestNG runner or your build configuration. Ensure the class name matches your package structure if the test class belongs to a package.

TestNG Assertions: Validating Expected Results

Assertions are essential because executing a method does not automatically prove that the application behaves correctly.

TestNG provides assertion methods through the org.testng.Assert class.

Common Assertion Methods

  • Assert.assertEquals(actual, expected) checks whether two values are equal.
  • Assert.assertTrue(condition) verifies that a condition is true.
  • Assert.assertFalse(condition) verifies that a condition is false.
  • Assert.assertNull(value) checks whether a value is null.
  • Assert.assertNotNull(value) checks whether a value is not null.
  • Assert.fail() explicitly fails a test.

For example:

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

public class ValidationTest {

    @Test
    public void testLoginStatus() {
        boolean loginSuccessful = true;

        Assert.assertTrue(loginSuccessful);
    }
}

The test passes because the condition is true.

In real automation projects, assertions should verify meaningful outcomes, such as the displayed confirmation message, the expected page title, or the returned API status.

TestNG Reports and Test Execution Results

Test reports help developers and testers understand what happened during a test run.

A report can show the number of tests passed, failed, or skipped, along with information that helps investigate failures.

Built-In HTML Reports

TestNG can generate standard HTML reports when executed with its default reporting configuration.

Look for the test-output directory after a TestNG run. The index.html report can be opened in a browser to review the results.

Maven Surefire Reports

When tests run through Maven Surefire, result files are typically generated in:

target/surefire-reports/

These files include test result summaries and XML output that can be used by reporting tools and continuous integration systems.

Custom Reports and Listeners

For more advanced reporting, TestNG listeners can capture test execution events. They can be integrated with logging systems, screenshot capture in Selenium projects, and custom reporting libraries.

For example, a listener can record additional information when a test fails, making it easier to diagnose the cause.

The standard TestNG reports and Maven reports are separate reporting mechanisms, so the available files depend on how the project is configured.

TestNG vs JUnit: What Is the Difference?

TestNG and JUnit are both Java testing frameworks. The best choice depends on the project’s needs and the team’s existing tools.

Feature TestNG JUnit
Test annotations Supported Supported
Data-driven tests @DataProvider Parameterized test facilities
Test grouping Groups through annotations and XML Tags and other organisation features
Test dependencies Supports dependency annotations Different approaches, depending on the JUnit version
XML suite configuration Supported Not the primary standard approach in JUnit
Integration with Java tools Supported Supported

TestNG offers convenient features for data-driven testing, groups, dependencies, and XML-based suite configuration. JUnit is also widely used and provides powerful testing capabilities.

Neither framework is universally better. Evaluate compatibility, project requirements, and team familiarity before choosing one.

Using TestNG With Selenium WebDriver

TestNG is frequently used alongside Selenium WebDriver to automate web application testing.

Selenium controls the browser, while TestNG organises test execution, runs test methods, checks outcomes, and reports results.

A typical Selenium and TestNG workflow involves:

  1. Configuring the Java project and dependencies.
  2. Initialising a browser through Selenium WebDriver.
  3. Opening the application under test.
  4. Interacting with page elements.
  5. Verifying the expected application behaviour using assertions.
  6. Closing the browser and reviewing test results.

For example, a login test may enter credentials, click the login button, and verify that the dashboard appears. TestNG manages the test method and its result, while Selenium performs the browser interactions.

When building this type of framework, keep browser setup and cleanup reliable, avoid hard-coded waits where possible, and ensure that tests can run independently.

Best Practices for Writing Effective TestNG Tests

Following good practices makes automated tests easier to understand, maintain, and troubleshoot.

Write Clear and Focused Test Methods

Each test should verify a meaningful behaviour. Descriptive method names help other developers understand the purpose of the test without reading every line of code.

Use Assertions Carefully

Assertions should verify expected behaviour rather than simply confirm that a method executed. Include useful messages where appropriate to make failures easier to diagnose.

Keep Test Data Separate

For tests with multiple input combinations, consider using DataProviders or external test data where appropriate. Keep sensitive credentials out of source code.

Avoid Unnecessary Dependencies Between Tests

Independent tests are generally more reliable and easier to execute in parallel. Use dependencies only when the workflow genuinely requires them.

Clean Up Resources

Close browser instances, release resources, and restore test data as necessary. Proper cleanup prevents one test from affecting another.

Review Reports After Execution

Investigate failures instead of repeatedly rerunning tests without understanding the cause. Check assertion messages, logs, configuration, and application behaviour.

Frequently Asked Questions About TestNG

1. What is TestNG used for?

TestNG is used to create, configure, and execute automated tests in Java. It supports annotations, data-driven testing, test groups, dependencies, listeners, and reporting.

2. Is TestNG suitable for beginners?

Yes. Beginners with basic Java knowledge can start with simple @Test methods and assertions before learning DataProviders, XML suites, and advanced configuration.

3. How do I install TestNG in a Java project?

You can add the TestNG dependency to a Maven or Gradle project, configure it manually if necessary, or use an appropriate IDE integration. Maven is a convenient option for managing dependencies.

4. How do I run TestNG tests using Maven?

Open a terminal in your project’s root directory and execute mvn test, provided your project and test runner are configured correctly.

5. What is the difference between @BeforeMethod and @BeforeClass?

@BeforeMethod executes before each applicable test method, whereas @BeforeClass executes once before the first test method in the class.

6. What is a DataProvider in TestNG?

A DataProvider is a method annotated with @DataProvider that supplies multiple data sets to a test method. This makes it possible to test different inputs without duplicating the test logic.

7. Can TestNG be used with Selenium?

Yes. TestNG can organise Selenium WebDriver tests, manage setup and cleanup, verify results through assertions, and generate execution reports.

8. Does TestNG support parallel testing?

Yes. TestNG supports parallel execution through its configuration options. Tests must be designed carefully to avoid conflicts involving shared state, test data, or browser instances.

9. Where are TestNG reports generated?

The standard TestNG HTML reports are commonly generated in the test-output directory. Maven Surefire reports are typically stored under target/surefire-reports.

10. Is TestNG better than JUnit?

Neither framework is the best choice for every project. TestNG offers features such as DataProviders, groups, dependencies, and XML suite configuration, while JUnit is also widely adopted and provides extensive testing capabilities.

Conclusion

TestNG is a useful Java testing framework for organising automated tests, validating application behaviour, managing test data, and reviewing execution results.

By learning annotations, assertions, DataProviders, test groups, XML suite configuration, and reporting, beginners can develop a strong foundation in Java-based automation testing.

The next step is to practise these concepts in a real project. Start with simple unit tests, introduce multiple data sets, and then explore integration with Selenium WebDriver and your preferred build tools.

For learners who want to strengthen their software testing knowledge, explore the training resources available at eLearning Solutions and continue developing practical skills in automation testing.

Keep practising, review test failures carefully, and build reliable automated tests one step at a time.

    Scroll to Top