Skip to content

Selenium - TestNG

TestNG is a popular open-source testing framework for Java, inspired by JUnit but introducing more powerful features suitable for complex test automation projects. Integrating Selenium WebDriver with TestNG provides a robust structure for organizing, executing, and reporting tests.

Key features and benefits of using TestNG with Selenium:

  • Annotations: Provides annotations (@Test, @BeforeMethod, @AfterMethod, @DataProvider, etc.) to control test lifecycle and structure.
  • Test Configuration: Flexible setup and teardown methods at different levels (Suite, Test, Class, Method).
  • Grouping: Allows grouping of test methods (e.g., ‘smoke’, ‘regression’, ‘sanity’).
  • Parallel Execution: Built-in support for running tests in parallel (methods, classes, tests) to speed up execution.
  • Parameterization: Easily pass parameters to tests, enabling data-driven testing (using @Parameters or @DataProvider).
  • Dependency Management: Define dependencies between test methods.
  • Reporting: Generates basic HTML reports and integrates well with reporting libraries like ExtentReports or Allure.

The recommended way to add TestNG to your project is via a build tool like Maven or Gradle. If using an IDE, you can also install the TestNG plugin:

  • Eclipse: Go to Help -> Eclipse Marketplace..., search for ‘TestNG’, and install ‘TestNG for Eclipse’.
  • IntelliJ IDEA: The TestNG plugin is usually bundled with IntelliJ IDEA. If not, go to File -> Settings -> Plugins, search for ‘TestNG’ in the Marketplace tab, and install it.

Remember to also add the TestNG dependency to your pom.xml (Maven) or build.gradle (Gradle) file as shown in the ‘Selenium - WebDriver’ chapter example.

Annotations control how TestNG executes your code:

AnnotationDescription
@TestMarks a method as a test case.
@BeforeSuite / @AfterSuiteExecuted once before/after all tests in the XML suite run.
@BeforeTest / @AfterTestExecuted before/after all test methods within the current <test> tag in the XML file.
@BeforeClass / @AfterClassExecuted once before/after the first/last test method in the current class is invoked.
@BeforeMethod / @AfterMethodExecuted before/after each method annotated with @Test.
@DataProviderMarks a method that supplies data to a test method. The test method must declare dataProvider="name".
@ParametersUsed to pass parameters defined in the testng.xml file to a test method.
@ListenersDefines test listeners (classes implementing ITestListener, ISuiteListener, etc.) for the test class.
@FactoryMarks a method as a factory for creating test class instances (advanced feature).

Let’s adapt the Google search example from the WebDriver chapter to demonstrate common TestNG annotations (@BeforeMethod, @AfterMethod, @Test).

package com.example.tests;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.*; // Import TestNG annotations
import java.time.Duration;
public class GoogleSearchTestNG {
WebDriver driver;
WebDriverWait wait;
// Runs before each @Test method in this class
@BeforeMethod
public void setupTest() {
System.out.println("Setting up WebDriver for test...");
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
wait = new WebDriverWait(driver, Duration.ofSeconds(10));
driver.manage().window().maximize();
}
// This is the actual test case
@Test(description = "Verify Google search functionality")
public void testGoogleSearch() {
System.out.println("Executing testGoogleSearch...");
driver.get("https://www.google.com");
WebElement searchBox = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("q")));
searchBox.sendKeys("TestNG Selenium");
searchBox.sendKeys(Keys.ENTER);
wait.until(ExpectedConditions.titleContains("TestNG Selenium"));
Assert.assertTrue(driver.getTitle().contains("TestNG Selenium"), "Title mismatch");
System.out.println("Search successful!");
}
// Another test case in the same class
@Test(description = "Verify Google page title")
public void testGoogleTitle() {
System.out.println("Executing testGoogleTitle...");
driver.get("https://www.google.com");
Assert.assertEquals(driver.getTitle(), "Google", "Homepage title mismatch");
System.out.println("Title verified!");
}
// Runs after each @Test method in this class
@AfterMethod
public void tearDownTest() {
System.out.println("Tearing down WebDriver...");
if (driver != null) {
driver.quit();
}
}
// Example using @BeforeClass / @AfterClass (runs once per class)
@BeforeClass
public void setupClass() {
System.out.println("--- Setting up resources for GoogleSearchTestNG class ---");
}
@AfterClass
public void tearDownClass() {
System.out.println("--- Cleaning up resources for GoogleSearchTestNG class ---");
}
}

While you can run individual test classes from your IDE, testng.xml provides more control over execution, including defining suites, tests, parameters, groups, and parallelism.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Selenium Test Suite">
<test name="Google Tests">
<classes>
<class name="com.example.tests.GoogleSearchTestNG"/>
<!-- Add other test classes here -->
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->

To run using the XML file: Right-click on testng.xml in your IDE and choose ‘Run As’ -> ‘TestNG Suite’.

After execution, TestNG provides feedback:

  • Console Output: Shows test execution progress and pass/fail status.
  • TestNG Results Window (IDE): Most IDE plugins provide a dedicated view showing test results in a tree format.
  • HTML Reports: TestNG generates basic HTML reports in the test-output folder (usually in your project root) detailing the execution results.

For more sophisticated reporting, consider integrating libraries like ExtentReports or Allure Test Report with TestNG using listeners.