{"id":71113,"date":"2025-01-30T18:06:52","date_gmt":"2025-01-30T12:36:52","guid":{"rendered":"https:\/\/www.guvi.in\/blog\/?p=71113"},"modified":"2026-08-11T23:50:44","modified_gmt":"2026-08-11T18:20:44","slug":"testng-annotations-and-its-uses","status":"publish","type":"post","link":"https:\/\/www.guvi.in\/blog\/testng-annotations-and-its-uses\/","title":{"rendered":"TestNG Annotations and Their Uses in Selenium Automation"},"content":{"rendered":"\n<p><strong>TestNG annotations are special markers in Java, prefixed with @, that tell the TestNG framework how and when to run each test method.<\/strong> <\/p>\n\n\n\n<p>They control the entire test lifecycle, from environment setup, through the actual test logic, to cleanup, making them the backbone of any structured <a href=\"https:\/\/www.selenium.dev\/\" target=\"_blank\" rel=\"noopener\">Selenium<\/a> automation framework.<\/p>\n\n\n\n<p>The most commonly used TestNG annotations are:<\/p>\n\n\n\n<ul>\n<li><strong>Setup annotations:<\/strong> @BeforeSuite, @BeforeTest, @BeforeClass, @BeforeMethod<\/li>\n\n\n\n<li><strong>Core annotation:<\/strong> @Test<\/li>\n\n\n\n<li><strong>Cleanup annotations:<\/strong> @AfterMethod, @AfterClass, @AfterTest, @AfterSuite<\/li>\n\n\n\n<li><strong>Data and configuration annotations:<\/strong> @DataProvider, @Parameters<\/li>\n\n\n\n<li><strong>Advanced annotations:<\/strong> @Listeners, @Factory<\/li>\n<\/ul>\n\n\n\n<p>Without this structure, a Selenium suite quickly turns into a pile of scripts with no clear setup, order, or cleanup.<\/p>\n\n\n\n<p>This guide covers their types, execution order, and practical use in Selenium, plus how they compare to JUnit, parallel execution, and the mistakes that break real automation frameworks.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What Are TestNG Annotations?<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_42_08-PM-1200x675.webp\" alt=\"What Are TestNG Annotations?\" class=\"wp-image-131786\" srcset=\"https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_42_08-PM-1200x675.webp 1200w, https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_42_08-PM-300x169.webp 300w, https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_42_08-PM-768x432.webp 768w, https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_42_08-PM-1536x864.webp 1536w, https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_42_08-PM-150x84.webp 150w, https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_42_08-PM.webp 1672w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" title=\"\"><\/figure>\n\n\n\n<p>TestNG annotations are special markers in <a href=\"https:\/\/www.guvi.in\/blog\/introduction-to-java\/\" target=\"_blank\" rel=\"noreferrer noopener\">Java<\/a> that provide instructions to the <a href=\"https:\/\/www.guvi.in\/blog\/a-quick-guide-to-testng-framework\/\" target=\"_blank\" rel=\"noreferrer noopener\">TestNG framework<\/a> about how to execute the test methods. These annotations define the life cycle of the test execution, such as before a test, after a test, or when the test should be skipped.<\/p>\n\n\n\n<p>TestNG annotations are defined by the&nbsp;@TestNG&nbsp;library and help organize the execution sequence of test methods, facilitating modular and scalable automation testing.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Why TestNG Annotations Matter in Selenium Automation<\/h3>\n\n\n\n<p>Before jumping into each annotation, here is a quick reference of all the major TestNG annotations and what they do:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>TestNG Annotation<\/th><th>Execution Timing<\/th><th>Primary Use<\/th><\/tr><\/thead><tbody><tr><td>@BeforeSuite<\/td><td>Once before all tests in the suite<\/td><td>Suite-level setup like WebDriver init<\/td><\/tr><tr><td>@BeforeTest<\/td><td>Before any test method in a &lt;test&gt; tag<\/td><td>Test group-level configuration<\/td><\/tr><tr><td>@BeforeClass<\/td><td>Once before first method in a class<\/td><td>Class-level browser or data setup<\/td><\/tr><tr><td>@BeforeMethod<\/td><td>Before every test method<\/td><td>Login, clear cookies before each test<\/td><\/tr><tr><td>@Test<\/td><td>Marks a method as a test case<\/td><td>Writing actual test logic<\/td><\/tr><tr><td>@AfterMethod<\/td><td>After every test method<\/td><td>Logout, take screenshot on failure<\/td><\/tr><tr><td>@AfterClass<\/td><td>Once after all methods in a class<\/td><td>Close browser at class level<\/td><\/tr><tr><td>@AfterTest<\/td><td>After all test methods in a &lt;test&gt; tag<\/td><td>Reset test-specific configurations<\/td><\/tr><tr><td>@AfterSuite<\/td><td>Once after all tests in the suite<\/td><td>Generate reports, release resources<\/td><\/tr><tr><td>@DataProvider<\/td><td>Provides data to test methods<\/td><td>Data-driven testing<\/td><\/tr><tr><td>@Parameters<\/td><td>Injects values from testng.xml<\/td><td>Environment or config-based testing<\/td><\/tr><tr><td>@Listeners<\/td><td>Attaches event listener classes<\/td><td>Custom reporting and logging<\/td><\/tr><tr><td>@Factory<\/td><td>Creates test instances dynamically<\/td><td>Running tests with different configs<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Commonly Used TestNG Annotations<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_46_49-PM-1200x675.webp\" alt=\"Commonly Used TestNG Annotations\" class=\"wp-image-131788\" srcset=\"https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_46_49-PM-1200x675.webp 1200w, https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_46_49-PM-300x169.webp 300w, https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_46_49-PM-768x432.webp 768w, https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_46_49-PM-1536x864.webp 1536w, https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_46_49-PM-150x84.webp 150w, https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_46_49-PM.webp 1672w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" title=\"\"><\/figure>\n\n\n\n<p>Below are the most commonly used TestNG annotations, their purposes, and how they can be leveraged in <a href=\"https:\/\/www.guvi.in\/blog\/becoming-a-selenium-expert\/\">Selenium<\/a> test scripts.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. @BeforeSuite, One of the Core TestNG Annotations<\/h3>\n\n\n\n<p><strong>Purpose:<\/strong> The @BeforeSuite annotation is executed once before any of the tests in the test suite are run. This is typically used to set up the environment for the entire suite, such as initializing WebDriver or reading configuration files.<\/p>\n\n\n\n<p><strong>Use Case:<\/strong><\/p>\n\n\n\n<ul>\n<li>Initializing Selenium WebDriver before running all tests in a suite.<\/li>\n\n\n\n<li>Setting up test environment (e.g., creating a database connection).<\/li>\n<\/ul>\n\n\n\n<p><strong>Example:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@BeforeSuite\npublic void setupSuite() {\n    \/\/ Code to initialize WebDriver or setup suite-level configurations\n    System.out.println(\"Before Suite: Setting up environment...\");\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2. @BeforeTest<\/h3>\n\n\n\n<p><strong>Purpose:<\/strong> This annotation is executed before any test methods inside a &lt;test&gt; tag are executed. It is useful for setting up preconditions for specific tests, like configuring a test database or logging into the application.<\/p>\n\n\n\n<p><strong>Use Case:<\/strong><\/p>\n\n\n\n<ul>\n<li>Logging in to the application before a set of tests runs.<\/li>\n\n\n\n<li>Configuring test-specific settings.<\/li>\n<\/ul>\n\n\n\n<p><strong>Example:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@BeforeTest\npublic void setupTest() {\n    \/\/ Code to setup test-specific configurations\n    System.out.println(\"Before Test: Setting up test environment...\");\n}<\/code><\/pre>\n\n\n\n<p><strong>Also read:<\/strong> <a href=\"https:\/\/www.guvi.in\/blog\/selenium-interview-questions-and-answers\/\">Top Selenium Interview Questions and Answers for 2026<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3. @BeforeClass<\/h3>\n\n\n\n<p><strong>Purpose:<\/strong> The @BeforeClass annotation is executed once before the first method in the current class is run. It is used for setting up resources needed specifically for the class.<\/p>\n\n\n\n<p><strong>Use Case:<\/strong><\/p>\n\n\n\n<ul>\n<li>Setting up a browser window or WebDriver before running all tests within the class.<\/li>\n\n\n\n<li>Initializing a set of data or configurations that are required for all tests in the class.<\/li>\n<\/ul>\n\n\n\n<p><strong>Example:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@BeforeClass\npublic void beforeClass() {\n    \/\/ Code to initialize browser or setup configurations\n    System.out.println(\"Before Class: Setting up browser...\");\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">4. @Test, the Most Used of All TestNG Annotations<\/h3>\n\n\n\n<p><strong>Purpose:<\/strong> The @Test annotation marks a method as a test case. This is the most commonly used annotation in TestNG. You can have multiple test methods in a class, each marked with the @Test annotation.<\/p>\n\n\n\n<p><strong>Use Case:<\/strong><\/p>\n\n\n\n<ul>\n<li>Writing actual test cases to validate functionalities like form submissions, login, navigation, etc.<\/li>\n\n\n\n<li>It can be used with parameters, assertions, and expected exceptions.<\/li>\n<\/ul>\n\n\n\n<p><strong>Key @Test attributes you should know:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Attribute<\/th><th>What It Does<\/th><\/tr><\/thead><tbody><tr><td>priority<\/td><td>Controls test execution order (lower number runs first)<\/td><\/tr><tr><td>enabled<\/td><td>Set to false to skip a test without deleting it<\/td><\/tr><tr><td>groups<\/td><td>Assigns the test to one or more groups<\/td><\/tr><tr><td>dependsOnMethods<\/td><td>Makes the test run only after another method passes<\/td><\/tr><tr><td>expectedExceptions<\/td><td>Passes the test only if a specific exception is thrown<\/td><\/tr><tr><td>timeOut<\/td><td>Fails the test if it takes longer than the given milliseconds<\/td><\/tr><tr><td>dataProvider<\/td><td>Links the test to a @DataProvider method for data-driven runs<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>Example:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Test\npublic void testLoginFunctionality() {\n    \/\/ Selenium WebDriver code for testing login functionality\n    Assert.assertTrue(driver.findElement(By.id(\"loginButton\")).isDisplayed());\n    System.out.println(\"Login test passed\");\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">5. @AfterClass<\/h3>\n\n\n\n<p><strong>Purpose:<\/strong> The @AfterClass annotation is executed after all the test methods in the current class have been run. It is used for cleanup tasks, such as closing the WebDriver or releasing any resources allocated for the class.<\/p>\n\n\n\n<p><strong>Use Case:<\/strong><\/p>\n\n\n\n<ul>\n<li>Closing the browser window after all tests in a class are complete.<\/li>\n\n\n\n<li>Clearing test data or disconnecting resources.<\/li>\n<\/ul>\n\n\n\n<p><strong>Example:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@AfterClass\npublic void afterClass() {\n    \/\/ Code to close browser\n    driver.quit();\n    System.out.println(\"After Class: Closing browser...\");\n}<\/code><\/pre>\n\n\n\n<p><strong>Explore:<\/strong> <a href=\"https:\/\/www.guvi.in\/blog\/becoming-a-selenium-expert\/\">Essential Steps to Becoming a Selenium Expert: Key Foundations<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">6. @AfterTest<\/h3>\n\n\n\n<p><strong>Purpose:<\/strong> This annotation is executed after all test methods in the &lt;test&gt; tag have been executed. It is useful for test-specific cleanup, such as logging out or resetting configurations that were set up before the test.<\/p>\n\n\n\n<p><strong>Use Case:<\/strong><\/p>\n\n\n\n<ul>\n<li>Logging out of an application after the tests are complete.<\/li>\n\n\n\n<li>Cleaning up or resetting configurations for the next test.<\/li>\n<\/ul>\n\n\n\n<p><strong>Example:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@AfterTest\npublic void afterTest() {\n    \/\/ Code to logout or clean up after the test\n    System.out.println(\"After Test: Cleaning up...\");\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">7. @AfterSuite<\/h3>\n\n\n\n<p><strong>Purpose:<\/strong> The @AfterSuite annotation is executed after all tests in the suite have been run. It is useful for performing cleanup tasks at the suite level, such as reporting or releasing suite-wide resources.<\/p>\n\n\n\n<p><strong>Use Case:<\/strong><\/p>\n\n\n\n<ul>\n<li>Generating a test report after all tests in the suite have completed.<\/li>\n\n\n\n<li>Closing connections or releasing suite-level resources.<\/li>\n<\/ul>\n\n\n\n<p><strong>Example:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@AfterSuite\npublic void teardownSuite() {\n    \/\/ Code to generate reports or cleanup after the entire suite\n    System.out.println(\"After Suite: Cleaning up after suite...\");\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">8. @DataProvider, One of the More Advanced TestNG Annotations<\/h3>\n\n\n\n<p><strong>Purpose:<\/strong> The @DataProvider annotation is used to provide data to a test method. It allows a test method to run multiple times with different inputs, which is useful for data-driven testing.<\/p>\n\n\n\n<p><strong>Use Case:<\/strong><\/p>\n\n\n\n<ul>\n<li>Running the same test with different sets of data, such as validating form submissions with various input values.<\/li>\n<\/ul>\n\n\n\n<p><strong>Example:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@DataProvider(name = \"loginData\")\npublic Object&#91;]&#91;] loginDataProvider() {\n    return new Object&#91;]&#91;] {\n        { \"user1\", \"password1\" },\n        { \"user2\", \"password2\" }\n    };\n}\n\n@Test(dataProvider = \"loginData\")\npublic void testLogin(String username, String password) {\n    \/\/ Selenium WebDriver code to perform login with provided data\n    Assert.assertTrue(login(username, password));\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">9. @BeforeMethod and @AfterMethod<\/h3>\n\n\n\n<p>These annotations are executed before and after each individual test method in a class.<\/p>\n\n\n\n<ul>\n<li><strong>@BeforeMethod:<\/strong> Used to set up any preconditions before each test method.<\/li>\n\n\n\n<li><strong>@AfterMethod:<\/strong> Used for cleanup tasks after each test method.<\/li>\n<\/ul>\n\n\n\n<p><strong>Use Case:<\/strong><\/p>\n\n\n\n<ul>\n<li>Setting up and tearing down individual tests, such as clearing cookies or logging in before each test.<\/li>\n<\/ul>\n\n\n\n<p><strong>Example:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@BeforeMethod\npublic void beforeMethod() {\n    \/\/ Code to initialize WebDriver or log in\n    System.out.println(\"Before Method: Logging in before each test...\");\n}\n\n@AfterMethod\npublic void afterMethod() {\n    \/\/ Code to logout or clear browser cache\n    System.out.println(\"After Method: Logging out after each test...\");\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">10. @Parameters, a Configuration-Focused TestNG Annotation<\/h3>\n\n\n\n<p><strong>Purpose:<\/strong> The @Parameters annotation injects values from the testng.xml configuration file directly into a test method. This is useful when you want to run the same tests against different browsers, environments, or configurations without changing code.<\/p>\n\n\n\n<p><strong>Use Cases:<\/strong><\/p>\n\n\n\n<ul>\n<li>Passing browser name (Chrome, Firefox) from testng.xml<\/li>\n\n\n\n<li>Passing base URL for different test environments (QA, staging, production)<\/li>\n<\/ul>\n\n\n\n<p><strong>Example:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Parameters({\"browser\", \"url\"})\n@BeforeTest\npublic void setup(String browser, String url) {\n    if (browser.equals(\"chrome\")) {\n        driver = new ChromeDriver();\n    } else if (browser.equals(\"firefox\")) {\n        driver = new FirefoxDriver();\n    }\n    driver.get(url);\n}<\/code><\/pre>\n\n\n\n<p>testng.xml configuration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;parameter name=\"browser\" value=\"chrome\"\/&gt;\n&lt;parameter name=\"url\" value=\"https:\/\/your-app.com\"\/&gt;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">11. @Listeners, an Advanced TestNG Annotation<\/h3>\n\n\n\n<p><strong>Purpose:<\/strong> The @Listeners annotation attaches one or more listener classes to your test class. Listeners are used to generate custom reports, log test events, take screenshots on failure, or integrate with third-party reporting tools like ExtentReports.<\/p>\n\n\n\n<p><strong>Use Cases:<\/strong><\/p>\n\n\n\n<ul>\n<li>Auto-capturing screenshots on test failure<\/li>\n\n\n\n<li>Integrating with ExtentReports or Allure for rich HTML reports<\/li>\n\n\n\n<li>Sending Slack or email notifications on test completion<\/li>\n<\/ul>\n\n\n\n<p><strong>Example:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Listeners(CustomTestListener.class)\npublic class LoginTest {\n    @Test\n    public void testLogin() {\n        \/\/ your test code\n    }\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">12. @Factory, the Most Advanced of the TestNG Annotations<\/h3>\n\n\n\n<p><strong>Purpose:<\/strong> The @Factory annotation creates test object instances dynamically at runtime. It is used when you want to run the same test class with different configurations without duplicating code.<\/p>\n\n\n\n<p><strong>Use Cases:<\/strong><\/p>\n\n\n\n<ul>\n<li>Running the same test class with different user roles (admin, guest, editor)<\/li>\n\n\n\n<li>Cross-browser testing with dynamically created test instances<\/li>\n<\/ul>\n\n\n\n<p><strong>Example:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Factory\npublic Object&#91;] createInstances() {\n    return new Object&#91;] {\n        new LoginTest(\"admin\", \"admin123\"),\n        new LoginTest(\"user\", \"user456\")\n    };\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>TestNG Annotations vs JUnit Annotations: Key Differences<\/strong><\/h2>\n\n\n\n<p>If you&#8217;ve worked with JUnit before, mapping TestNG annotations to their closest JUnit equivalent makes the transition much faster, since both frameworks use annotations for the same core purpose. The two frameworks overlap a lot conceptually, but TestNG&#8217;s annotation set is noticeably richer.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>TestNG Annotation<\/th><th>Closest JUnit 5 Equivalent<\/th><th>Key Difference<\/th><\/tr><\/thead><tbody><tr><td>@BeforeSuite \/ @AfterSuite<\/td><td>No direct equivalent<\/td><td>JUnit has no native suite-level lifecycle hook<\/td><\/tr><tr><td>@BeforeTest \/ @AfterTest<\/td><td>No direct equivalent<\/td><td>JUnit lacks TestNG&#8217;s <code>&lt;test&gt;<\/code> tag grouping concept<\/td><\/tr><tr><td>@BeforeClass \/ @AfterClass<\/td><td>@BeforeAll \/ @AfterAll<\/td><td>Functionally similar; JUnit 5 requires the method to be static<\/td><\/tr><tr><td>@BeforeMethod \/ @AfterMethod<\/td><td>@BeforeEach \/ @AfterEach<\/td><td>Functionally similar across both frameworks<\/td><\/tr><tr><td>@Test<\/td><td>@Test<\/td><td>Same core purpose in both<\/td><\/tr><tr><td>@DataProvider<\/td><td>@ParameterizedTest + @MethodSource<\/td><td>JUnit needs two annotations combined to match one TestNG annotation<\/td><\/tr><tr><td>@Parameters<\/td><td>No clean native equivalent<\/td><td>JUnit typically relies on external config or Spring&#8217;s @Value<\/td><\/tr><tr><td>@Listeners<\/td><td>@ExtendWith<\/td><td>Both attach custom behaviour, but the underlying extension model differs<\/td><\/tr><tr><td>@Factory<\/td><td>No direct equivalent<\/td><td>JUnit 5 uses @TestFactory for dynamic tests, which works differently<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>Where TestNG clearly wins:<\/strong> native parallel execution via testng.xml (parallel=&#8221;methods&#8221;, thread-count), a built-in priority attribute for controlling test order, and suite\/group-level configuration without extra plugins.<\/p>\n\n\n\n<p><strong>Where JUnit 5 has caught up:<\/strong> it added parallel execution support from version 5.3 onward, and @Order now lets you control method execution order, closing part of the gap that used to clearly favour TestNG.<\/p>\n\n\n\n<p>For Selenium automation specifically, TestNG annotations remain the more popular choice in India&#8217;s IT services and product companies, mainly because of the native suite-level configuration and simpler parallel execution setup.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>TestNG Annotations Execution Order<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_50_00-PM-1200x675.webp\" alt=\"TestNG Annotations Execution Order\" class=\"wp-image-131790\" srcset=\"https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_50_00-PM-1200x675.webp 1200w, https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_50_00-PM-300x169.webp 300w, https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_50_00-PM-768x432.webp 768w, https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_50_00-PM-1536x864.webp 1536w, https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_50_00-PM-150x84.webp 150w, https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-11_50_00-PM.webp 1672w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" title=\"\"><\/figure>\n\n\n\n<p>One of the most frequently asked questions about TestNG annotations is: in what order do they actually run? Here is the complete execution order for a single test class:<\/p>\n\n\n\n<p><em><strong>@BeforeSuite \u2192 @BeforeTest \u2192 @BeforeClass \u2192 @BeforeMethod \u2192 @Test \u2192 @AfterMethod \u2192 @AfterClass \u2192 @AfterTest \u2192 @AfterSuite<\/strong><\/em><\/p>\n\n\n\n<p>For a complete suite with multiple classes, TestNG annotations fire as follows:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Step<\/th><th>TestNG Annotation<\/th><th>Runs<\/th><\/tr><\/thead><tbody><tr><td>1<\/td><td>@BeforeSuite<\/td><td>Once at the very start<\/td><\/tr><tr><td>2<\/td><td>@BeforeTest<\/td><td>Once per <code>&lt;test&gt;<\/code> tag in testng.xml<\/td><\/tr><tr><td>3<\/td><td>@BeforeClass<\/td><td>Once per class<\/td><\/tr><tr><td>4<\/td><td>@BeforeMethod<\/td><td>Before every @Test method<\/td><\/tr><tr><td>5<\/td><td>@Test<\/td><td>Each test method<\/td><\/tr><tr><td>6<\/td><td>@AfterMethod<\/td><td>After every @Test method<\/td><\/tr><tr><td>7<\/td><td>@AfterClass<\/td><td>Once per class<\/td><\/tr><tr><td>8<\/td><td>@AfterTest<\/td><td>Once per &lt;test&gt; tag in testng.xml<\/td><\/tr><tr><td>9<\/td><td>@AfterSuite<\/td><td>Once at the very end<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Key Uses of TestNG Annotations in Selenium Automation<\/strong><\/h2>\n\n\n\n<ol>\n<li><strong>Test Organization and Setup<\/strong>: Annotations like&nbsp;@BeforeSuite,&nbsp;@BeforeClass, and&nbsp;@BeforeTest&nbsp;help organize the setup for a test suite, class, or individual test cases, allowing for better maintainability and structure.<\/li>\n\n\n\n<li><strong>Efficient Test Execution<\/strong>: Annotations like&nbsp;@Test&nbsp;allow you to define multiple test methods, which can be run in parallel or sequentially. The use of&nbsp;@DataProvider&nbsp;further enhances test execution by running tests with different data sets.<\/li>\n\n\n\n<li><strong>Resource Management<\/strong>: Annotations like&nbsp;@AfterSuite,&nbsp;@AfterTest, and&nbsp;@AfterClass&nbsp;make it easy to perform cleanup tasks such as closing WebDriver sessions or releasing any external resources after tests have run.<\/li>\n\n\n\n<li><strong>Flexible and Scalable<\/strong>: TestNG allows you to group tests, run them in parallel, and apply different annotations depending on your needs. This makes it highly flexible and scalable for large test suites.<\/li>\n\n\n\n<li><strong>Error Handling and Reporting<\/strong>: TestNG provides mechanisms for handling test failures, generating reports, and capturing logs. The annotations allow testers to structure their tests in a way that enhances visibility and debugging.<\/li>\n<\/ol>\n\n\n\n<p>TestNG annotations streamline automation by managing test execution, parallel runs, and exception handling. But theory alone isn\u2019t enough, real-world application is key.<\/p>\n\n\n\n<p>Looking to master Selenium automation? Get hands-on with HCL GUVI&#8217;s <a href=\"https:\/\/www.guvi.in\/zen-class\/selenium-automation-testing-course\/?utm_source=blog&amp;utm_medium=hyperlink&amp;utm_campaign=testng_annotations\" data-type=\"link\" data-id=\"https:\/\/www.guvi.in\/zen-class\/selenium-automation-testing-course\/?utm_source=blog&amp;utm_medium=hyperlink&amp;utm_campaign=testng_annotations\" target=\"_blank\" rel=\"noreferrer noopener\">Selenium Automation Testing Course<\/a> and learn to implement TestNG effectively in scalable frameworks.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>How to Skip or Disable Tests Using TestNG Annotations<\/strong><\/h2>\n\n\n\n<p>Not every test should run every time, and TestNG annotations give you a few clean ways to control that.<\/p>\n\n\n\n<p><strong>Option 1: Disable a test entirely using TestNG annotations.<\/strong> Set enabled = false on the @Test annotation, and TestNG will skip it completely without deleting the method:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Test(enabled = false)\npublic void testUnderMaintenance() {\n    \/\/ This test is temporarily skipped\n}<\/code><\/pre>\n\n\n\n<p><strong>Option 2: Skip conditionally at runtime, another approach among TestNG annotations.<\/strong> Throw a SkipException inside the test method when a specific condition isn&#8217;t met, which is useful when the decision to skip depends on data only available while the test is running:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Test\npublic void testPremiumFeature() {\n    if (!userIsPremium) {\n        throw new SkipException(\"Skipping: user is not a premium account\");\n    }\n    \/\/ premium-only test logic\n}<\/code><\/pre>\n\n\n\n<p><strong>Option 3: Exclude entire groups.<\/strong> Tag tests with groups = {&#8220;flaky&#8221;} and exclude that group in testng.xml, which is the cleanest way to skip a whole category of tests without touching individual test methods:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;groups&gt;\n    &lt;run&gt;\n        &lt;exclude name=\"flaky\"\/&gt;\n    &lt;\/run&gt;\n&lt;\/groups&gt;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>TestNG Annotations for Parallel Test Execution<\/strong><\/h2>\n\n\n\n<p>Parallel execution is one of the strongest reasons teams choose TestNG annotations over JUnit for large Selenium suites. There are two levels of control.<\/p>\n\n\n\n<p><strong>Suite-level parallelism<\/strong>, controlled through TestNG annotations and settings in testng.xml, controls how TestNG splits work across threads:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;suite name=\"MySuite\" parallel=\"methods\" thread-count=\"4\"&gt;<\/code><\/pre>\n\n\n\n<p>The parallel attribute accepts methods, tests, classes, or instances, depending on how granular you want the parallelism to be.<\/p>\n\n\n\n<p><strong>Method-level parallelism<\/strong>, one of the finer-grained TestNG annotations settings, set directly on @Test, lets a single test method run multiple times concurrently, useful for load-style checks:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Test(threadPoolSize = 3, invocationCount = 9)\npublic void testConcurrentLogins() {\n    \/\/ Runs 9 times, 3 threads at a time\n}<\/code><\/pre>\n\n\n\n<p>A word of caution: parallel execution only works reliably if your WebDriver instances are thread-safe, typically by making the driver a ThreadLocal variable rather than a shared static field. Skipping this step is one of the most common causes of flaky parallel Selenium suites.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Best Practices for Organizing TestNG Annotations in a Selenium Framework<\/strong><\/h2>\n\n\n\n<p>Knowing what each of these TestNG annotations does is one thing; using them well in a real framework is another.<\/p>\n\n\n\n<ul>\n<li><strong>Keep WebDriver initialization at the class or suite level<\/strong>, not inside @BeforeMethod, unless every test genuinely needs a fresh browser instance.<\/li>\n\n\n\n<li><strong>Use @BeforeMethod for state, not setup.<\/strong> Clearing cookies, resetting the URL, or logging in belongs here; expensive one-time setup does not.<\/li>\n\n\n\n<li><strong>Group tests meaningfully<\/strong> with the <code>groups<\/code> attribute (smoke, regression, sanity) so CI pipelines can run a fast subset instead of the full suite on every commit.<\/li>\n\n\n\n<li><strong>Keep listeners centralized.<\/strong> Like most TestNG annotations meant for suite-wide behaviour, register @Listeners once at the suite level in testng.xml rather than repeating it across every test class.<\/li>\n\n\n\n<li><strong>Avoid deeply nested dependsOnMethods chains.<\/strong> A test that depends on a test that depends on another test is fragile; keep dependency chains shallow or avoid them where possible.<\/li>\n\n\n\n<li><strong>Externalize environment values with @Parameters<\/strong> instead of hardcoding browser names or URLs, so the same suite can run against QA, staging, and production without code changes.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Common Mistakes to Avoid with TestNG Annotations<\/strong><\/h2>\n\n\n\n<p>These are the mistakes that break automation frameworks in real projects:<\/p>\n\n\n\n<ul>\n<li><strong>Putting WebDriver initialization in @BeforeMethod when it should be in @BeforeClass:<\/strong> If each @Test creates and destroys a browser, your suite will be slow and unstable. Initialize WebDriver at the class level unless each test truly needs a fresh browser.<\/li>\n\n\n\n<li><strong>Not using @AfterMethod for screenshot capture:<\/strong> Skipping this means you have no visual evidence when a test fails in a CI pipeline.<\/li>\n\n\n\n<li><strong>Using @BeforeSuite for test-specific logic:<\/strong> @BeforeSuite runs once for everything. Test-specific setup belongs in @BeforeTest or @BeforeClass.<\/li>\n\n\n\n<li><strong>Ignoring the priority attribute of @Test:<\/strong> Without priorities, TestNG annotations execute test methods alphabetically by default, which often produces incorrect results for ordered workflows like checkout flows.<\/li>\n\n\n\n<li><strong>Not using groups with @Test:<\/strong> In large suites, running all tests every time is wasteful. Using groups like &#8220;smoke&#8221;, &#8220;regression&#8221;, &#8220;sanity&#8221; with @Test and targeting them in testng.xml speeds up feedback loops dramatically.<\/li>\n<\/ul>\n\n\n\n<div style=\"background-color: #099f4e; border: 3px solid #110053; border-radius: 12px; padding: 18px 22px; color: #FFFFFF; font-size: 18px; font-family: Montserrat, Helvetica, sans-serif; line-height: 1.6; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); max-width: 750px; margin: 22px auto;\">\n  <h3 style=\"margin-top: 0; font-size: 22px; font-weight: 700; color: #ffffff;\">\ud83d\udca1 Did You Know?<\/h3>\n  <ul style=\"padding-left: 20px; margin: 10px 0;\">\n    <li>TestNG was created by Cedric Beust in 2004 as a more powerful alternative to JUnit, and &#8220;NG&#8221; stands for Next Generation. Despite being over 20 years old, it remains the dominant test framework for Java Selenium automation in 2026.<\/li>\n    <li>The @DataProvider TestNG annotation can be combined with parallel execution to run data-driven tests simultaneously, reducing total test execution time by up to 70% in large suites.<\/li>\n    <li>TestNG annotations are fully supported in all major CI\/CD platforms including Jenkins, GitHub Actions, and GitLab CI, making them a critical skill for any automation engineer working in a DevOps environment. Knowing your TestNG annotations inside out is what separates junior testers from senior automation engineers in 2026.<\/li>\n    <li>According to job posting analysis on LinkedIn and Naukri.com, TestNG is mentioned in over 65% of Selenium automation testing job descriptions for Indian IT companies in 2026, making it the most in-demand testing framework alongside Selenium.<\/li>\n  <\/ul>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<p>Mastering TestNG annotations isn\u2019t just about ticking technical boxes\u2014it\u2019s about creating a well-oiled testing framework that can adapt to real-world complexities. By strategically using annotations like @BeforeSuite or @DataProvider, you\u2019re not just managing tests but optimizing workflows for better results.<\/p>\n\n\n\n<p>Think of TestNG as the backbone of your Selenium automation\u2014helping you execute tests with precision while ensuring your framework remains robust and scalable. The more fluently you incorporate these annotations into your testing strategy, the more seamless and effective your automation efforts will become. Here&#8217;s to building better testing processes, one annotation at a time!<\/p>\n\n\n\n<p>TestNG annotations streamline automation by managing test execution, parallel runs, and exception handling. But theory alone is not enough, real-world application is key. Looking to master Selenium automation? Get hands-on with HCL GUVI&#8217;s <a href=\"https:\/\/www.guvi.in\/zen-class\/selenium-automation-testing-course\/?utm_source=blog&amp;utm_medium=hyperlink&amp;utm_campaign=testng_annotations\" target=\"_blank\" data-type=\"link\" data-id=\"https:\/\/www.guvi.in\/zen-class\/selenium-automation-testing-course\/?utm_source=blog&amp;utm_medium=hyperlink&amp;utm_campaign=testng_annotations\" rel=\"noreferrer noopener\">Selenium Automation Testing Course<\/a> and learn to implement TestNG annotations effectively in scalable frameworks.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>FAQs<\/strong><\/h2>\n\n\n<div id=\"rank-math-faq\" class=\"rank-math-block\">\n<div class=\"rank-math-list \">\n<div id=\"faq-question-1779689275761\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">1. What are TestNG annotations?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>TestNG annotations are special markers in Java prefixed with @ that tell the TestNG framework how to manage the lifecycle of test execution. Each TestNG annotation has a specific role: @Test marks a method as a test case, @BeforeSuite sets up the environment before any test runs, and @DataProvider feeds multiple data sets to a single test method.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1779689302328\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">2. What is the execution order of TestNG annotations?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>The execution order of TestNG annotations is: @BeforeSuite, @BeforeTest, @BeforeClass, @BeforeMethod, @Test, @AfterMethod, @AfterClass, @AfterTest, and @AfterSuite. Understanding this order is essential for writing stable Selenium test frameworks.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1779689330730\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">3. What is the difference between @BeforeMethod and @BeforeClass in TestNG?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>@BeforeClass runs once before all test methods in a class. @BeforeMethod runs before every individual @Test method. Use @BeforeClass for one-time setup like browser initialization. Use @BeforeMethod for per-test setup like logging in or clearing cookies before each test case.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1779689361440\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \"><strong>4. How does @DataProvider work in TestNG?<\/strong><\/h3>\n<div class=\"rank-math-answer \">\n\n<p>The @DataProvider TestNG annotation returns a two-dimensional Object array. Each row in the array is passed as a separate set of arguments to the linked @Test method, causing it to run multiple times with different data. This is the foundation of data-driven testing in Selenium with TestNG.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1779689383252\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \"><strong>5. What is the use of @Parameters in TestNG annotations?<\/strong><\/h3>\n<div class=\"rank-math-answer \">\n\n<p>The @Parameters TestNG annotation reads values from the testng.xml file and injects them into a test method at runtime. This allows you to run the same test against different browsers, environments, or configurations without modifying your test code. It is widely used for cross-browser testing.<\/p>\n\n<\/div>\n<\/div>\n<\/div>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>TestNG annotations are special markers in Java, prefixed with @, that tell the TestNG framework how and when to run each test method. They control the entire test lifecycle, from environment setup, through the actual test logic, to cleanup, making them the backbone of any structured Selenium automation framework. The most commonly used TestNG annotations [&hellip;]<\/p>\n","protected":false},"author":65,"featured_media":71216,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[40,706],"tags":[],"views":"5955","authorinfo":{"name":"Jebasta","url":"https:\/\/www.guvi.in\/blog\/author\/jebasta\/"},"thumbnailURL":"https:\/\/www.guvi.in\/blog\/wp-content\/uploads\/2025\/01\/TestNG-Annotations-300x112.webp","_links":{"self":[{"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/posts\/71113"}],"collection":[{"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/users\/65"}],"replies":[{"embeddable":true,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/comments?post=71113"}],"version-history":[{"count":16,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/posts\/71113\/revisions"}],"predecessor-version":[{"id":131791,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/posts\/71113\/revisions\/131791"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/media\/71216"}],"wp:attachment":[{"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/media?parent=71113"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/categories?post=71113"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.guvi.in\/blog\/wp-json\/wp\/v2\/tags?post=71113"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}