Comprehensive Guide to TestNG for Java Automation Testing
TestNG Setup and Basic Usage
To begin using TestNG in a Java project, configure your environment with Maven. Add the following dependency to your pom.xml file:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>TestProject</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
After adding the dependency, create a test class in your IDE. Use the @Test annotation to mark test methods. For example:
import org.testng.annotations.Test;
public class SampleTest {
@Test
public void verifyAddition() {
System.out.println("Executing addition test");
}
}
Run the test class directly from your IDE or via Maven commands.
Key TestNG Annotations
TestNG provides several annnotations to control test execution flow:
| Annotation | Purpose |
|---|---|
@BeforeSuite |
Executes once before all tests in the suite |
@AfterSuite |
Executes once after all tests in the suite |
@BeforeTest |
Runs before any test method in a <test> tag |
@AfterTest |
Runs after all test methods in a <test> tag |
@BeforeClass |
Executes before the first test method in the current class |
@AfterClass |
Executes after all test methods in the current class |
@BeforeMethod |
Runs before each test method |
@AfterMethod |
Runs after each test method |
@DataProvider |
Suplies data to test methods |
@Factory |
Creates test class instances dynamically |
@Listeners |
Defines custom listeners for test events |
@Parameters |
Passes parameters from XML configurasion |
@Test |
Marks a method as a test case |
Here's an example demonstrating execution order:
import org.testng.annotations.*;
public class AnnotationDemo {
@BeforeSuite
public void setupSuite() {
System.out.println("Suite setup");
}
@BeforeClass
public void setupClass() {
System.out.println("Class setup");
}
@BeforeMethod
public void setupMethod() {
System.out.println("Method setup");
}
@Test
public void testOne() {
System.out.println("Test one execution");
}
@Test
public void testTwo() {
System.out.println("Test two execution");
}
@AfterMethod
public void cleanupMethod() {
System.out.println("Method cleanup");
}
@AfterClass
public void cleanupClass() {
System.out.println("Class cleanup");
}
@AfterSuite
public void cleanupSuite() {
System.out.println("Suite cleanup");
}
}
Execution output:
Suite setup
Class setup
Method setup
Test one execution
Method cleanup
Method setup
Test two execution
Method cleanup
Class cleanup
Suite cleanup
Assertions in TestNG
TestNG includes assertion methods for validation:
assertEquals(actual, expected)- Verifies equalityassertNotEquals(actual, unexpected)- Verifies inequalityassertTrue(condition)- Checks if condition is trueassertFalse(condition)- Checks if condition is falseassertNull(object)- Verifies object is nullassertNotNull(object)- Verifies object is not nullassertSame(expected, actual)- Checks object referencesassertNotSame(unexpected, actual)- Verifies different referencesassertArrayEquals(expectedArray, actualArray)- Compares arrays
Example usage:
import org.testng.Assert;
import org.testng.annotations.Test;
public class AssertionExamples {
@Test
public void validateCalculations() {
int result = 5 + 3;
Assert.assertEquals(result, 8, "Addition should return 8");
Assert.assertNotEquals(result, 10, "Result should not be 10");
Assert.assertTrue(result > 0, "Result should be positive");
}
}
Running Tests with Maven
Configure the Maven Surefire plugin to execute TestNG tests:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
Test Configuration Options
Disabling Tests
Use enabled = false to skip test execution:
@Test(enabled = false)
public void disabledTest() {
System.out.println("This won't run");
}
Timeout Configuration
Set maximum execution time with timeOut:
@Test(timeOut = 2000)
public void timeLimitedTest() throws InterruptedException {
Thread.sleep(1500); // Passes within timeout
}
@Test(timeOut = 500)
public void failingTimeoutTest() {
while(true) {} // Exceeds timeout, fails
}
Grouping Tests
Organize tests into groups for selective execution:
@Test(groups = {"smoke", "regression"})
public void smokeAndRegressionTest() {
System.out.println("Running smoke and regression test");
}
@Test(groups = "regression")
public void regressionOnlyTest() {
System.out.println("Running regression test");
}
Configure group execution in testng.xml:
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="TestSuite">
<test name="RegressionTests">
<groups>
<run>
<include name="regression"/>
</run>
</groups>
<classes>
<class name="com.example.TestClass"/>
</classes>
</test>
</suite>
Test Execution Order
Control method execution sequence with priority:
@Test(priority = 1)
public void firstTest() {
System.out.println("First to execute");
}
@Test(priority = 3)
public void thirdTest() {
System.out.println("Third to execute");
}
@Test(priority = 2)
public void secondTest() {
System.out.println("Second to execute");
}
Test Dependencies
Define dependencies between test methods:
@Test
public void prerequisiteTest() {
System.out.println("Must run first");
}
@Test(dependsOnMethods = "prerequisiteTest")
public void dependentTest() {
System.out.println("Runs after prerequisite");
}
If the prerequisite test fails, dependent tests are skipped.
Parameterized Testing
XML-Based Parameters
Pass parameters through test configuration:
@Test
@Parameters({"username", "password"})
public void loginTest(String user, String pass) {
System.out.println("Testing login with: " + user + "/" + pass);
}
testng.xml configuration:
<suite name="ParameterSuite">
<test name="LoginTests">
<parameter name="username" value="testuser"/>
<parameter name="password" value="secret123"/>
<classes>
<class name="com.example.LoginTests"/>
</classes>
</test>
</suite>
DataProvider Parameters
Use @DataProvider for complex parameter sets:
@DataProvider(name = "userCredentials")
public Object[][] provideUserData() {
return new Object[][] {
{"alice", "alice123"},
{"bob", "bob456"},
{"charlie", "charlie789"}
};
}
@Test(dataProvider = "userCredentials")
public void multiUserLogin(String username, String password) {
System.out.println("Testing: " + username);
}
This executes the test method three times with different data sets.