Next-Gen App & Browser Testing Cloud
Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

Learn how to use TestNG annotations for Selenium-based automation testing. We will look at an example for each annotation along with their attributes.
Sadhvi Singh
January 31, 2026
TestNG is a testing framework created by CĂŠdric Beust and helps to cater a lot of our testing needs. It is widely used in Selenium. Wondering on what NG stands for? Well, it refers to âNext Generationâ. TestNG is similar to Junit but is more powerful to it when it comes to controlling the execution flow of your program. As the nature of framework, we tend to make our tests more structured and provides better validation points through the use of TestNG Annotations.
TestNG Annotations are special markers in Java (starting with @) that control the flow and structure of test execution in TestNG. They tell the framework when to execute setup, teardown, and test methods making automation scripts cleaner, modular, and easier to maintain.
What Are TestNG Annotations?
TestNG annotations define the test lifecycle from initialization to cleanup, without relying on XML configuration alone. Each annotation performs a specific role, like setting up before tests (@BeforeMethod) or running actions after all tests (@AfterSuite).
They also manage dependencies, groups, data inputs, and test order, helping testers build flexible and reusable automation frameworks.
Core TestNG Annotations and Their Roles
Execution Order in TestNG (Most Asked in Interviews)
The standard execution hierarchy is:
@BeforeSuite â @BeforeTest â @BeforeClass â @BeforeMethod â @Test â @AfterMethod â @AfterClass â @AfterTest â @AfterSuite
Important Annotation Attributes You Should Know
These attributes help fine-tune test behavior for better reliability and speed.
Best Practices for Using TestNG Annotations
Some of the noteworthy features of TestNG are:
A basic process flow of a TestNG programs involves the following steps:

So, before jumping onto the annotations in TestNG for Selenium automation, it would be better to refer the prerequisites are required to setup TestNG.
Prerequisites
Note: Annotations can be used only with Java version 1.5 or higher.
If you are new to TestNG framework then follow our guide to run your first automation script with TestNG.
If youâre new to Selenium and wondering what it is then we recommend checking out our guide â What is Selenium?
An annotation is a tag that provides additional information about the class or method. It is represented by â@â prefix. TestNG use these annotations to help in making a robust framework. Let us have a look at these annotations of TestNG for Selenium.
The most important TestNG annotations framework where the main business logic resides. All functionalities to be automated are kept inside the @Test annotation method. It has various attributes based on which the method can be reformed and executed.
Example of a code snippet below validating the url :
@Test
public void testCurrentUrl() throws InterruptedException
{
driver.findElement(By.xpath("//*[@id='app']/header/aside/ul/li[4]/a")).click();
String currentUrl= driver.getCurrentUrl();
assertEquals(current_url, "https://automation.lambdatest.com/timeline/?viewType=build&page=1", "url did not matched");
}
This annotation is run before your first @Test TestNG Annotations method in your class. You can use this annotation in TestNG for Selenium to setup your browser profile preferences, for example auto opening your browser in maximize mode, setting up your own customized profile for your browser etc.
Below is the code snippet for BeforeTest method ensuring the browser opens in maximize mode:
@BeforeTest
public void profileSetup()
{
driver.manage().window().maximize();
}
This TestNG Annotations runs after all your test methods belonging to your class have run. This is a useful annotation which comes handy in terms of reporting your automation results to your stakeholders. You can use this annotation to generate report of your tests and share it to your stakeholders via email.
Example of the code snippet below:
@AfterTest
public void reportReady()
{
System.out.println("Report is ready to be shared, with screenshots of tests");
}
This annotation in TestNG runs before every @test annotated method. You can use it to check out for the database connections before executing your tests or lets say different functionality been tested in your @test annotated method which requires user login in a certain class. In this case also you can put your login code in the @BeforeMethod annotation method.
Below code snippet is an example, displaying login functionality of the TestMu AI platform:
@BeforeMethod
public void checkLogin()
{
driver.get("https://accounts.lambdatest.com/login");
driver.findElement(By.xpath("//input[@name='email']")).sendKeys("[email protected]");
driver.findElement(By.xpath("//input[@name='password']")).sendKeys("XXXXX");
driver.findElement(By.xpath("//*[@id='app']/section/form/div/div/button")).click();
}
This annotation runs after every @test annotated method. This annotation can be used to take screenshots of every test method ran against test runs .
Below code snippet indicating screenshot taken in the @AfterTest TestNG Annotations for Selenium:
@AfterMethod
public void screenShot() throws IOException
{
TakesScreenshot scr= ((TakesScreenshot)driver);
File file1= scr.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file1, new File("C:\Users\navyug\workspace\QAPractise\test-output\test1.PNG"));
}
This annotation runs before the first test method in the current class.This annotation can be used to setup your browser properties, initialize your driver, opening your browser with the desired URL etc.
Below is the code snippet for BeforeClass:
@BeforeClass
public void appSetup()
{
driver.get(url);
}
This TestNG Annotations runs after the last test method in the current class. This annotation in TestNG can be used to perform clean up activities during your tests like closing your driver etc
Below is the example of code snippet showing closing activities performed:
@AfterClass
public void closeUp()
{
driver.close();
}
A suite can consist of multiple classes, this TestNG Annotations runs before all the tests methods of all the classes. This annotation marks the entry point of execution. @BeforeSuite annotation in TestNG can be used to perform the needed and generic functions like setting up and starting Selenium drivers or remote web drivers etc.
Example of @BeforeSuite annotation in TestNG, code snippet showcasing setting up of driver:
@BeforeSuite
public void setUp()
{
System.setProperty("webdriver.chrome.driver", "path to chrome driver");
driver=new ChromeDriver();
}
Explore what WebDriver is, its features, how it works, best practices, and more in this WebDriver Tutorial.
This TestNG Annotations runs post all the test methods of all the classes have run. This annotation can be used to clean up the processes before completing off your tests when you have multiple classes in functioning, for example closing the drivers etc.
Below is the code snippet for @AfterSuite annotation in TestNG for Selenium:
@AfterSuite
public void cleanUp()
{
System.out.println("All close up activities completed");
}
TestNG helps testers create a bunch of tests into groups through the attribute group used in the @Test TestNG Annotations. For example, if you wish all similar functionalities related to user management to be clubbed together, you can mark all tests like Dashboard, profile, transactions etc. into a single group as âuser_managementâ. This @BeforeGroups annotation in TestNG helps to run the defined test first before the specified group. This annotation can be used if the group focuses on a single functionality like stated in the above example. The BeforeGroup annotation can contain the login feature which is required to run before any other methods like user dashboard, user profile etc.
Example of the Code snippet for @BeforeGroups annotation in TestNG for Selenium:
@BeforeGroups("urlValidation")
public void setUpSecurity() {
System.out.println("url validation test starting");
}
This TestNG Annotations runs after all the test methods of the specified group are executed. Example of Code snippet for @AfterGroups annotation in TestNG for Selenium:
@AfterGroups("urlValidation")
public void tearDownSecurity() {
System.out.println("url validation test finished");
}
The below code displays an example of all annotations used along with TestNG report respectively:
import static org.testng.Assert.assertEquals;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
public class AnnotationsTestNG {
public WebDriver driver;
public String url="https://www.lambdatest.com/";
@BeforeSuite
public void setUp()
{
System.setProperty("webdriver.chrome.driver", "C:\Users\navyug\workspace\QAPractise\src\ChromeDriver\chromedriver.exe");
driver=new ChromeDriver();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
System.out.println("The setup process is completed");
}
@BeforeTest
public void profileSetup()
{
driver.manage().window().maximize();
System.out.println("The profile setup process is completed");
}
@BeforeClass
public void appSetup()
{
driver.get(url);
System.out.println("The app setup process is completed");
}
@BeforeMethod
public void checkLogin()
{
driver.get("https://accounts.lambdatest.com/login");
driver.findElement(By.xpath("//input[@name='email']")).sendKeys("[email protected]");
driver.findElement(By.xpath("//input[@name='password']")).sendKeys("activa9049");
driver.findElement(By.xpath("//*[@id='app']/section/form/div/div/button")).click();
System.out.println("The login process on lamdatest is completed");
}
@Test(groups="urlValidation")
public void testCurrentUrl() throws InterruptedException
{
driver.findElement(By.xpath("//*[@id='app']/header/aside/ul/li[4]/a")).click();
Thread.sleep(6000);
String currentUrl= driver.getCurrentUrl();
assertEquals(currentUrl, "https://automation.lambdatest.com/timeline/?viewType=build&page=1", "url did not matched");
System.out.println("The url validation test is completed");
}
@AfterMethod
public void screenShot() throws IOException
{
TakesScreenshot scr= ((TakesScreenshot)driver);
File file1= scr.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file1, new File("C:\Users\navyug\workspace\QAPractise\test-output\test1.PNG"));
System.out.println("Screenshot of the test is taken");
}
@AfterClass
public void closeUp()
{
driver.close();
System.out.println("The close_up process is completed");
}
@AfterTest
public void reportReady()
{
System.out.println("Report is ready to be shared, with screenshots of tests");
}
@AfterSuite
public void cleanUp()
{
System.out.println("All close up activities completed");
}
@BeforeGroups("urlValidation")
public void setUpSecurity() {
System.out.println("url validation test starting");
}
@AfterGroups("urlValidation")
public void tearDownSecurity() {
System.out.println("url validation test finished");
}
}

Deliver immersive digital experiences with Next-Generation Mobile Apps and Cross Browser Testing Cloud
With TestNG certification, you can challenge your skills in performing automated testing with TestNG and take your career to the next level.
Hereâs a short glimpse of the TestNG certification from TestMu AI:


Watch this video to learn how to set up and use TestNG with Selenium to automate your testing process. We will also introduce the TestNG Priority method, which allows you to write easy-to-read and maintainable tests.
All TestNG Annotations described above are executed on runtime in the following order:
Here is an image of the basic workflow of these annotations:

These test annotations in TestNG have multiple attributes that can be used for our test method. The attributes further help in defining our tests and help in providing clarity in terms of execution flow of the different testâs method used in the TestNG class. Listing them below:
@Test(description=âthis test validates the login functionalityâ).@Test(alwaysRun= true).@Test(dataProvider=âcross browser testingâ).@Test(dependsOnmethod=âLoginâ).@Test(groups=âPayment_Moduleâ). This attribute also helps in the longer run when one can choose to ignore few groups during the execution cycle and chose over the other groups. All one need to do is mention the included groups in the TestNG.xml file within the include tag whereas the excluded groups can be defined using the exclude tag in the xml file.@Test(dependsOnMethods = "Payment_Module" ).@Test(priority=1), @Test(priority=2), in this case test with priority equal to one will be executed first then the test with priority as 2.@Test(enabled= false).@Test(timeOut= 500). Please note the time specified is in milliseconds.@Test(invocationCount = 5), this would execute the test 5 times.@Test(invocationCount =5,invocationTimeOut = 20 ).@Test(expectedExceptions = {ArithmeticException.class }).The above defined are the attributes used with the annotations in TestNG for Selenium. Below is the code snippet showcasing the use of the above attributes:
import static org.testng.Assert.assertEquals;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
public class AnnotationsTest {
public WebDriver driver;
public String url="https://www.lambdatest.com/";
@BeforeSuite
public void setUp()
{
System.setProperty("webdriver.chrome.driver", "C:\Users\navyug\workspace\QAPractise\src\ChromeDriver\chromedriver.exe");
driver=new ChromeDriver();
System.out.println("The setup process is completed");
}
@BeforeTest
public void profileSetup()
{
driver.manage().window().maximize();
System.out.println("The profile setup process is completed");
}
@BeforeClass
public void appSetup()
{
driver.get(url);
System.out.println("The app setup process is completed");
}
@Test(priority=2)
public void checkLogin()
{
driver.get("https://accounts.lambdatest.com/login");
driver.findElement(By.xpath("//input[@name='email']")).sendKeys("[email protected]");
driver.findElement(By.xpath("//input[@name='password']")).sendKeys("xxxxx");
driver.findElement(By.xpath("//*[@id='app']/section/form/div/div/button")).click();
System.out.println("The login process on lamdatest is completed");
}
@Test(priority=0 ,description= "this test validates the sign-up test")
public void signUp() throws InterruptedException
{
WebElement link= driver.findElement(By.xpath("//a[text()='Free Sign Up']"));
link.click();
WebElement organization=driver.findElement(By.xpath("//input[@name='organization_name']"));
organization.sendKeys("LambdaTest");
WebElement firstName=driver.findElement(By.xpath("//input[@name='name']"));
firstName.sendKeys("Test");
WebElement email=driver.findElement(By.xpath("//input[@name='email']"));
email.sendKeys("[email protected]");
WebElement password=driver.findElement(By.xpath("//input[@name='password']"));
password.sendKeys("TestUser123");
WebElement phoneNumber=driver.findElement(By.xpath("//input[@name='phone']"));
phoneNumber.sendKeys("9412262090");
WebElement termsOfService=driver.findElement(By.xpath("//input[@name='terms_of_service']"));
termsOfService.click();
WebElement button=driver.findElement(By.xpath("//button[text()='Signup']"));
button.click();
}
@Test(priority=3, alwaysRun= true, dependsOnMethods="check_login", description="this test validates the URL post logging in" , groups="url_validation")
public void testCurrentUrl() throws InterruptedException
{
driver.findElement(By.xpath("//*[@id='app']/header/aside/ul/li[4]/a")).click();
String currentUrl= driver.getCurrentUrl();
assertEquals(current_url, "https://automation.lambdatest.com/timeline/?viewType=build&page=1", "url did not matched");
System.out.println("The url validation test is completed");
}
@Test(priority=1, description = "this test validates the logout functionality" ,timeOut= 25000)
public void logout() throws InterruptedException
{
Thread.sleep(6500);
driver.findElement(By.xpath("//*[@id='userName']")).click();
driver.findElement(By.xpath("//*[@id='navbarSupportedContent']/ul[2]/li/div/a[5]")).click();
}
@Test(enabled=false)
public void skipMethod()
{
System.out.println("this method will be skipped from the test run using the attribute enabled=false");
}
@Test(priority=6,invocationCount =5,invocationTimeOut = 20)
public void invocationcountShowCaseMethod()
{
System.out.println("this method will be executed by 5 times");
}
@AfterMethod()
public void screenshot() throws IOException
{
TakesScreenshot scr= ((TakesScreenshot)driver);
File file1= scr.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file1, new File("C:\Users\navyug\workspace\QAPractise\test-output\test1.PNG"));
System.out.println("Screenshot of the test is taken");
}
@AfterClass
public void closeUp()
{
driver.close();
System.out.println("The close_up process is completed");
}
@AfterTest
public void reportReady()
{
System.out.println("Report is ready to be shared, with screenshots of tests");
}
@AfterSuite
public void cleanUp()
{
System.out.println("All close up activities completed");
}
@BeforeGroups("urlValidation")
public void setUpSecurity() {
System.out.println("url validation test starting");
}
@AfterGroups("urlValidation")
public void tearDownSecurity() {
System.out.println("url validation test finished");
}
}


Watch this video to learn about the TestNG Annotations and how they help provide better structure and readability to the code.
There are more annotations than the ones defined above, which are used for desired purpose only.
This annotated method is used for supplying data to the test method in which the dataProvider attribute is defined. This annotated method helps in creating a data driven framework where multiple sets of input values can be given which returns a 2D array or object. @DataProvider annotation in TestNG comes with two attributes.
Below is the code snippet indicating the use of @DataProvider annotation with name and parallel attribute set to it.
@DataProvider(name="SetEnvironment", parallel=true)
public Object[][] getData(){
Object[][] browserProperty = new Object[][]{
{Platform.WIN8, "chrome", "70.0"},
{Platform.WIN8, "chrome", "71.0"}
};
return browserProperty;
}
This annotation helps to run multiple test classes through a single test class. It basically defines and create tests dynamically.
The below code snippet indicates the use of @Factory annotation that helps calls the test method class.
package ChromeDriver;
import org.testng.annotations.Test;
public class FactorySimplyTest1 {
@Test
public void testMethod1() {
System.out.println("This is to test for method 1 for Factor Annotation");
}}
package ChromeDriver;
import org.testng.annotations.Test;
public class FactorySimpleTest2 {
@Test
public void testMethod2() {
System.out.println("This is to test for method 2 for Factor Annotation");
}
}
package ChromeDriver;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
public class FactoryAnnotation {
@Factory()
@Test
public Object[] getTestFactoryMethod() {
Object[] factoryTest = new Object[2];
factoryTest[0] = new FactorySimplyTest1();
factoryTest[1] = new FactorySimpleTest2();
return factoryTest;
}
}

This annotation helps you pass parameters to your tests directly via the testNG.xml file. Usually this is preferred when you have limited data sets to try on your tests. In case of complicated and large data sets @dataProvider annotation is preferred or excel.
The below code snippet showcase the same:
@Parameters({ "username", "password"})
@Test()
public void checkLogin(String username, String password)
{
driver.get("https://accounts.lambdatest.com/login");
driver.findElement(By.xpath("//input[@name='email']")).sendKeys(username);
driver.findElement(By.xpath("//input[@name='password']")).sendKeys(password);
driver.findElement(By.xpath("//*[@id='app']/section/form/div/div/button")).click();
System.out.println("The login process on lamdatest is completed");
}
The parameter values are defined in the TestNG.xml file as below:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Annotations">
<parameter name="username" value="[email protected]" />
<parameter name="password" value="XXXXX" />
<classes>
<class name="Parameter_annotation"/>
</classes>
</test> <!-- Annotations -->
</suite> <!-- Suite -->
This annotation helps in logging and reporting. We have multiple listeners like:
But to go in depth with these listeners and their uses would be a talk for another blog. I will be writing one soon, so stay tuned.
If you want to know more about Event Listeners In Selenium WebDriver watch this video to learn how the Listeners âlistenâ to the event defined in the Selenium script and behave accordingly.
The key point to note while working with all these annotations and attributes is your system should have java 1.5 version or higher as these annotations are not supported for all lower versions of java and you may tend to receive error for them.
For an all in one session on performing a complete TestNG tutorial with Selenium you can checkout this video.
All the above mentioned TestNG Annotations and attributes of TestNG helps to provide better structuring and readability to the code. It helps provide detailed reports that makes status reporting part even easier and useful. Use of these annotations in TestNG for Selenium completely depend on your business requirements. Hence, choosing the right ones for the right use is important. If youâre interested in exploring more about TestNG, check out our comprehensive TestNG interview questions guide. Try out these annotations in TestNG on TestMu AI Selenium Grid now!
Did you find this page helpful?
More Related Hubs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance