<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"><suitename="Test Suite"parallel="methods"thread-count="5"verbose="1"><!-- Suite-level parameters --><parametername="browser"value="chrome"/><parametername="environment"value="staging"/><!-- Define test groups --><testname="Smoke Tests"><groups><run><includename="smoke"/><excludename="slow"/></run></groups><!-- Specify test classes --><classes><classname="com.example.LoginTest"/><classname="com.example.SearchTest"><!-- Include specific methods --><methods><includename="testBasicSearch"/><includename="testAdvancedSearch"/></methods></class></classes></test><!-- Another test configuration --><testname="Regression Tests"><packages><packagename="com.example.regression.*"/></packages></test><!-- Listeners --><listeners><listenerclass-name="com.example.CustomListener"/></listeners></suite>
<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>3.0.0</version><configuration><!-- Specify suite files --><suiteXmlFiles><suiteXmlFile>testng.xml</suiteXmlFile><suiteXmlFile>smoke-tests.xml</suiteXmlFile></suiteXmlFiles><!-- Run specific groups --><groups>smoke,regression</groups><excludedGroups>slow,manual</excludedGroups><!-- Parallel execution --><parallel>methods</parallel><threadCount>5</threadCount><!-- System properties --><systemPropertyVariables><browser>chrome</browser><environment>staging</environment></systemPropertyVariables><!-- Continue on failures --><testFailureIgnore>false</testFailureIgnore></configuration></plugin></plugins></build>
test{useTestNG(){// Suite filessuites'src/test/resources/testng.xml'// Include/exclude groupsincludeGroups'smoke','regression'excludeGroups'slow'// Parallel executionparallel='methods'threadCount=5// Preserve orderpreserveOrder=true// Group by instancesgroupByInstances=true}// System propertiessystemProperty'browser','chrome'systemProperty'environment','staging'// Test outputtestLogging{events"passed","skipped","failed"exceptionFormat"full"}}
Use Case 1: Basic Test Class with Setup and Teardown¶
importorg.testng.annotations.*;importorg.testng.Assert;publicclassUserManagementTest{privateDatabaseConnectiondb;privateUserServiceuserService;@BeforeClasspublicvoidsetupClass(){// Initialize database connection once for all testsdb=newDatabaseConnection("jdbc:mysql://localhost:3306/testdb");db.connect();}@BeforeMethodpublicvoidsetupMethod(){// Create fresh service instance before each testuserService=newUserService(db);}@Test(priority=1,groups={"smoke"})publicvoidtestCreateUser(){Useruser=userService.createUser("john@example.com","John Doe");Assert.assertNotNull(user.getId());Assert.assertEquals(user.getEmail(),"john@example.com");}@Test(priority=2,dependsOnMethods={"testCreateUser"})publicvoidtestFindUser(){Useruser=userService.findByEmail("john@example.com");Assert.assertNotNull(user);Assert.assertEquals(user.getName(),"John Doe");}@AfterMethodpublicvoidcleanupMethod(){// Clean up test data after each testuserService.deleteAllUsers();}@AfterClasspublicvoidcleanupClass(){// Close database connection after all testsdb.disconnect();}}
Use Case 2: Data-Driven Testing with DataProvider¶
importorg.testng.annotations.*;importorg.testng.Assert;publicclassLoginTest{privateLoginPageloginPage;@BeforeMethodpublicvoidsetup(){loginPage=newLoginPage();loginPage.open();}@DataProvider(name="loginCredentials")publicObject[][]getLoginData(){returnnewObject[][]{{"valid@user.com","ValidPass123",true,"Dashboard"},{"invalid@user.com","WrongPass",false,"Invalid credentials"},{"","password",false,"Email is required"},{"user@test.com","",false,"Password is required"},{"admin@test.com","AdminPass!",true,"Admin Panel"}};}@Test(dataProvider="loginCredentials")publicvoidtestLogin(Stringemail,Stringpassword,booleanshouldSucceed,StringexpectedMessage){loginPage.enterEmail(email);loginPage.enterPassword(password);loginPage.clickLogin();if(shouldSucceed){Assert.assertTrue(loginPage.isLoggedIn());Assert.assertEquals(loginPage.getPageTitle(),expectedMessage);}else{Assert.assertTrue(loginPage.hasError());Assert.assertTrue(loginPage.getErrorMessage().contains(expectedMessage));}}@AfterMethodpublicvoidteardown(){loginPage.close();}}
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"><suitename="Parallel Test Suite"parallel="tests"thread-count="3"><testname="Chrome Tests"parallel="methods"thread-count="2"><parametername="browser"value="chrome"/><groups><run><includename="smoke"/></run></groups><classes><classname="com.example.tests.HomePageTest"/><classname="com.example.tests.SearchTest"/></classes></test><testname="Firefox Tests"parallel="methods"thread-count="2"><parametername="browser"value="firefox"/><groups><run><includename="smoke"/></run></groups><classes><classname="com.example.tests.HomePageTest"/><classname="com.example.tests.SearchTest"/></classes></test><testname="API Tests"parallel="classes"thread-count="3"><groups><run><includename="api"/></run></groups><packages><packagename="com.example.api.*"/></packages></test></suite>
// Test class using parameterspublicclassCrossBrowserTest{privateWebDriverdriver;@Parameters({"browser"})@BeforeMethodpublicvoidsetup(Stringbrowser){if(browser.equalsIgnoreCase("chrome")){driver=newChromeDriver();}elseif(browser.equalsIgnoreCase("firefox")){driver=newFirefoxDriver();}driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));}@Test(groups={"smoke"})publicvoidtestHomePage(){driver.get("https://example.com");Assert.assertEquals(driver.getTitle(),"Example Domain");}@AfterMethodpublicvoidteardown(){if(driver!=null){driver.quit();}}}
importorg.testng.IRetryAnalyzer;importorg.testng.ITestResult;// Retry analyzer for flaky testspublicclassRetryAnalyzerimplementsIRetryAnalyzer{privateintretryCount=0;privatestaticfinalintMAX_RETRY=3;@Overridepublicbooleanretry(ITestResultresult){if(retryCount<MAX_RETRY){retryCount++;returntrue;}returnfalse;}}// API Test classpublicclassAPITest{privateRestClientclient;@BeforeClasspublicvoidsetup(){client=newRestClient("https://api.example.com");}@Test(groups={"api"},retryAnalyzer=RetryAnalyzer.class)publicvoidtestGetUser(){Responseresponse=client.get("/users/1");Assert.assertEquals(response.getStatusCode(),200);Assert.assertNotNull(response.jsonPath().getString("name"));}@Test(groups={"api"},dependsOnMethods={"testGetUser"})publicvoidtestCreateUser(){Stringpayload="{\"name\":\"John\",\"email\":\"john@test.com\"}";Responseresponse=client.post("/users",payload);Assert.assertEquals(response.getStatusCode(),201);}@Test(groups={"api"},timeOut=5000)publicvoidtestPerformance(){longstartTime=System.currentTimeMillis();Responseresponse=client.get("/users");longendTime=System.currentTimeMillis();Assert.assertEquals(response.getStatusCode(),200);Assert.assertTrue((endTime-startTime)<3000,"API response time exceeded 3 seconds");}}
Use meaningful test names: Name tests clearly to describe what they verify (e.g., testUserCanLoginWithValidCredentials instead of test1)
Leverage groups effectively: Organize tests into logical groups (smoke, regression, api, ui) to run subsets of tests based on context and save execution time
Implement proper setup and teardown: Use @BeforeMethod/@AfterMethod for test-level setup and @BeforeClass/@AfterClass for expensive operations like database connections
Make tests independent: Each test should be self-contained and not rely on execution order or shared state. Use dependsOnMethods sparingly and only when logical dependency exists
Use DataProviders for test data: Separate test data from