Comprehensive TestNG Tutorial: A Complete Guide to TestNG Framework for Java Testing


1. What is TestNG Framework?

TestNG is a testing framework for Java that simplifies and enhances the process of writing and running tests. TestNG stands for "Next Generation Testing" and is designed to cover all categories of tests, including unit, functional, end-to-end, and integration tests. It was inspired by JUnit and NUnit but provides additional features and flexibility.

We'll learn about all the interesting features of the TestNG Framework in this TestNG Tutorial.

Table of Content

1. Introduction to TestNG
  • What is TestNG Framework?
  • Benefits of TestNG
  • TestNG vs. JUnit
  • Install TestNG in Eclipse
2. TestNG Annotations
  • 2.1 @Test Annotation
    • 2.1.1 Priority
    • 2.1.2 Skipping Tests - Enabled
    • 2.1.3 Test Dependency - DependensOnMethods
    • 2.1.4 Groups
    • 2.1.5 Timeout
  • 2.2 Configuration Annotations
    • 2.2.1 @BeforeSuite and @AfterSuite
    • 2.2.2 @BeforeTest and @AfterTest
    • 2.2.3 @BeforeClass and @AfterClass
    • 2.2.4 @BeforeMethod and @AfterMethod
  • 2.3 Additional Annotations
    • 2.3.1 @DataProvider
    • 2.3.2 @Parameters
    • 2.3.3 @Factory
    • 2.3.4 @Listeners
3. TestNG Test Configuration
  • 3.1 TestNG XML Configuration
  • 3.2 Suite Configuration
  • 3.3 Test Configuration
  • 3.4 Class Configuration
  • 3.5 Method Configuration
4. Parameterization in TestNG
  • 4.1 Parameterizing Test Methods
  • 4.2 Parameterizing Test Classes
  • 4.3 Parameterizing Test Suites
5. TestNG Assertions
  • 5.1 Using Assertions in TestNG
  • 5.2 Asserting Exceptions
6. TestNG Parallel Execution
  • 6.1 Configuring Parallel Execution
  • 6.2 Parallel Test Methods
  • 6.3 Parallel Test Classes
  • 6.4 Parallel Test Suites
7. TestNG Reporting and TestNG Plugins
  • 7.1 Default HTML Reports
  • 7.2 Generating Customized Test Reports
  • 7.3 TestNG Plugins and Extensions
8. TestNG Integration with Selenium
  • 8.1 Setting Up Selenium with TestNG
  • 8.2 Writing Selenium Test Cases with TestNG
  • 8.3 Running Selenium Tests with TestNG
  • 8.4 Data-Driven Testing with Selenium and TestNG

9. TestNG Listeners

10. TestNG Data Providers
  • 10.1 Understanding Data Providers
  • 10.2 Creating Data Providers
  • 10.3 Data Provider Parameters
  • 10.4 Data Provider with Excel
  • 10.5 Data Provider with CSV

11. TestNG Page Factory

12. TestNG and Continuous Integration
  • 12.1 Integrating TestNG with Jenkins
  • 12.2 Running TestNG Tests in CI/CD Pipeline
  • 12.3 Configuring TestNG in Maven

                  1.1. Key features of TestNG include

                  1. Annotation-based: TestNG allows you to use annotations to define test methods, configure test execution, and manage test dependencies. Annotations provide a way to define pre- and post-test actions, setup and teardown methods, and more.

                  2. Parallel Test Execution: TestNG supports parallel test execution, allowing you to run tests in parallel on multiple threads or even on multiple machines. This can significantly reduce test execution time and provide faster feedback.

                  3. Flexible Test Configuration: TestNG provides various configuration options through XML or Java-based configuration files. You can define test suites, test groups, test dependencies, and more, allowing you to customize and control the test execution flow.

                  4. Data-Driven Testing: TestNG supports data-driven testing, where you can supply different sets of test data to a test method and execute it multiple times with different inputs. This is useful for testing various scenarios with different data sets.

                  5. TestNG Assertions: TestNG provides a rich set of assertion methods that allow you to validate the expected behavior of your application under test. Assertions help in verifying the correctness of test results and identifying failures.

                  1.2 Benefits of TestNG

                  TestNG offers several benefits over traditional testing frameworks like JUnit:

                  1. Powerful Annotations: TestNG's annotations provide more flexibility and control over test execution compared to JUnit. Annotations like @BeforeSuite, @AfterSuite, @BeforeTest, @AfterTest, @BeforeClass, @AfterClass, @BeforeMethod, and @AfterMethod allow you to define setup and teardown methods at various levels.

                  2. Parallel Test Execution: TestNG allows you to run tests in parallel, which can significantly reduce test execution time, especially for large test suites. It supports parallel execution at the method, class, or suite level, enabling faster feedback.

                  3. Test Configuration Flexibility: TestNG provides multiple configuration options, including XML-based configuration files and programmatic configuration using Java classes. This flexibility allows you to define test suites, test dependencies, test groups, and more, according to your specific testing requirements.

                  4. Data-Driven Testing: TestNG's data-driven testing capabilities enable you to test your application with multiple data sets. This is particularly useful for parameterized testing, where you can test a single piece of functionality with various input combinations.

                  5. Reporting and Test Output: TestNG generates detailed test reports that provide comprehensive information about test execution, including test results, test timings, failures, and more. These reports can be customized and integrated with other reporting frameworks for better visibility into test results.

                  1.3 TestNG vs. JUnit

                  While both TestNG and JUnit are popular testing frameworks for Java, there are some notable differences:

                  FeaturesTestNGJUnit
                  Annotation SupportProvides a rich set of annotations for test configuration, setup, and teardown methods.Offers a set of annotations for test configuration and lifecycle methods.
                  Parallel ExecutionBuilt-in support for parallel test execution, allowing tests to run concurrently.Requires additional libraries or plugins for parallel test execution.
                  Test ConfigurationOffers extensive configuration options through XML-based configuration files and programmatic configuration.Relies primarily on annotations for test configuration and doesn't have built-in XML-based configuration.
                  Data-Driven TestingBuilt-in support for data-driven testing, enabling tests to be executed with multiple data sets.Requires additional libraries or custom code to achieve data-driven testing.
                  ReportingGenerates detailed HTML reports by default, providing comprehensive test execution information.Relies on third-party libraries or plugins for generating reports.
                  FlexibilityProvides more flexibility in defining test suites, test dependencies, and customizing test execution flow.Offers less flexibility compared to TestNG.
                  PopularityWidely used in enterprise-level testing and preferred by some automation frameworks.Popular for unit testing and widely used in the Java community.

                  It's important to note that both TestNG and JUnit are powerful testing frameworks with their own strengths and capabilities. The choice between them depends on the specific needs and preferences of the testing project.


                  1.4. Installing TestNG in Eclipse

                  1. Open Eclipse.
                  2. Click on the 'Help' menu option.
                  3. Click on "Eclipse Marketplace"
                  You need to install the TestNG plugin in your Eclipse to work with it. Below are the steps:



                  4. Type TestNG in the Find text box and click on the search icon. After TestNG is appeared in the search click on the Install button.


                  5. After clicking Install, it will show some other dialogues, just click Accept the terms and click Finish.
                  6. Installation will take some time to complete.
                  7. Eclipse will ask you to restart, click yes.
                  8. After restarting, you can verify if TestNG is installed correctly or not. Click Window -> Preferences, TestNG should display in the Preferences list.


                  2. TestNG Annotations

                  TestNG provides a set of annotations that allow you to control the behavior and execution flow of your tests. In this tutorial, we will explore the different annotations provided by TestNG and their usage.

                  2.1. @Test Annotation

                  The @Test annotation is the most commonly used annotation in TestNG. It marks a method as a test method. Here's an example:

                  java
                  @Test public void testMethod() { // Test logic goes here }

                  You can add additional attributes to the @Test annotation to customize the behavior of the test method, such as:

                  • priority: Specifies the priority of the test method.
                  • enabled: Controls whether the test method should be executed or skipped.
                  • dependsOnMethods: Specifies the methods on which the current test method depends.
                  • groups: Assigns the test method to one or more groups for grouping and filtering tests.

                  2.2. Attributes of @Test Annotation

                  I. What is Priority in TestNG?

                  The priority attribute is used to define the execution priority of the test method. Test methods with higher priority values are executed first. The default priority is 0 if not specified.

                  java
                  @Test(priority = 1) public void highPriorityTest() { // Test logic goes here } @Test(priority = 2) public void mediumPriorityTest() { // Test logic goes here } @Test(priority = 3) public void lowPriorityTest() { // Test logic goes here }


                  Example Code for Priority in TestNG:

                  Here's an example code snippet that demonstrates the usage of the @Test annotation with the priority the attribute in TestNG:

                  java
                  import org.testng.annotations.Test; public class TestngPriority { @Test(priority = 0) public void one() { System.out.println("This is test case 1"); } @Test(priority = 2) public void two() { System.out.println("This is test case 2"); } @Test(priority = 1) public void three() { System.out.println("This is test case 3"); } @Test(priority = 3) public void four() { System.out.println("This is test case 4"); } }

                  In the above code, we have a test class TestngPriority with four test methods: one(), two(), three(), and four(). Each test method is annotated with the @Test annotation, and we have specified the priority attribute for each method.

                  Based on the specified priorities, TestNG will execute the test methods in the ascending order of their priorities. In this case, the output of the test execution will be as follows:

                  bash
                  This is test case 1 This is test case 3 This is test case 2 This is test case 4

                  As you can see, the test methods are executed in the order defined by their priorities: 0, 1, 2, and 3.

                  The @Test annotation with the priority attribute allows you to control the order in which test methods are executed, ensuring that tests with higher priorities are executed first. This can be useful when you have dependencies between test methods or when you want to prioritize certain tests based on their significance.


                  II. enabled in TestNG

                  The enabled attribute controls whether the test method should be executed or skipped. By default, the value is true, which means the test method is enabled for execution. If set to false, the test method will be skipped.

                  java
                  @Test(enabled = false) public void disabledTestMethod() { // This test method will be skipped } @Test public void enabledTestMethod() { // This test method will be executed }

                  If you execute the tests using TestNG's test runner, you will see the following output in the console:

                  markdown
                  =============================================== Default Suite Total tests run: 2, Failures: 0, Skips: 1 ===============================================

                  In this case, the disabledTestMethod() will be skipped because it has the enabled attribute set to false, and the enabledTestMethod() will be executed.

                  The output indicates that 2 tests were run in the default test suite, with no failures and 1 skip.


                  III. dependsOnMethods in TestNG

                  The dependsOnMethods the attribute allows you to specify dependencies between test methods. It ensures that a test method is executed only if the specified dependent methods have passed successfully.

                  java
                  @Test public void loginTest() { // Test logic for login } @Test(dependsOnMethods = "loginTest") public void dashboardTest() { // Test logic for dashboard functionality }

                  In the example above, the dashboardTest method will only be executed if the loginTest method has passed successfully.

                  Example Code:

                  Here's an example code snippet that demonstrates method dependencies in TestNG:

                  java
                  import org.testng.annotations.Test; public class TestngDependencies { @Test public void openBrowser() { System.out.println("Opening the browser"); } @Test(dependsOnMethods = "openBrowser") public void signIn() { System.out.println("Signing in"); } @Test(dependsOnMethods = {"openBrowser", "signIn"}) public void logOut() { System.out.println("Logging out"); } }

                  Program Explanation:

                  In the above code, we have a test class TestngDependencies with three test methods: openBrowser(), signIn(), and logOut(). We have specified the method dependencies using the dependsOnMethods attribute of the @Test annotation.

                  • The signIn() method is dependent on the openBrowser() method, so it will be executed only if the openBrowser() method has passed successfully.
                  • The logOut() method is dependent on both the openBrowser() and signIn() methods, so it will be executed only if both the openBrowser() and signIn() methods have passed successfully.

                  Below is the execution sequence of the above code snippet:

                  1. OpenBrowser
                  2. SignIn
                  3. LogOut.

                  When you execute the test methods, TestNG will ensure that the dependencies are satisfied and execute the methods accordingly. The output of the test execution will be as follows:

                  csharp
                  Opening the browser Signing in Logging out

                  As you can see, the methods are executed in the order defined by their dependencies: openBrowser(), signIn(), and logOut().


                  IV. groups in TestNG

                  The groups attribute is used to assign test methods to one or more groups. Groups are used for grouping and filtering tests. You can specify multiple groups by separating them with commas.

                  java
                  @Test(groups = "smoke") public void smokeTest() { // Test logic goes here } @Test(groups = {"sanity", "regression"}) public void sanityAndRegressionTest() { // Test logic goes here }

                  You can then specify which groups of tests to include or exclude when running tests using TestNG configuration.

                  xml
                  <test name="MyTest"> <groups> <run> <include name="smoke" /> </run> </groups> </test>

                  In the above example, only the test method with the smoke group will be executed.

                  Example Code for  Groups:

                  Here's an example code snippet to demonstrate the usage of groups in TestNG:

                  java
                  import org.testng.annotations.Test; public class TestngGroups { @Test(groups = "smoke") public void smokeTest1() { System.out.println("Executing smoke test 1"); } @Test(groups = "smoke") public void smokeTest2() { System.out.println("Executing smoke test 2"); } @Test(groups = "regression") public void regressionTest1() { System.out.println("Executing regression test 1"); } @Test(groups = {"regression", "sanity"}) public void regressionAndSanityTest() { System.out.println("Executing regression and sanity test"); } }

                  In the above code, we have a test class TestngGroups with four test methods. Each test method is assigned to one or more groups using the groups attribute of the @Test annotation.

                  • smokeTest1() and smokeTest2() are assigned to the smoke group.
                  • regressionTest1() is assigned to the regression group.
                  • regressionAndSanityTest() is assigned to both the regression and sanity groups.

                  Now, when executing the tests, you can include or exclude specific groups to control which tests are executed. This can be done using TestNG configuration, such as testng.xml or programmatically.

                  For example, if you want to execute only the tests in the smoke group, you can include the group in the configuration as follows:

                  xml
                  <test name="SmokeTests"> <groups> <run> <include name="smoke" /> </run> </groups> <classes> <class name="com.example.TestngGroups" /> </classes> </test>

                  In this case, only the smokeTest1() and smokeTest2() methods will be executed.

                  On the other hand, if you want to execute the tests in the regression group but exclude the sanity group, you can configure it as follows:

                  xml
                  <test name="RegressionTests"> <groups> <run> <include name="regression" /> <exclude name="sanity" /> </run> </groups> <classes> <class name="com.example.TestngGroups" /> </classes> </test>

                  In this case, the regressionTest1() and regressionAndSanityTest() methods will be executed, but the regressionAndSanityTest() method will not be considered part of the test run because it is also assigned to the sanity group.


                  2.2 Configuration Annotations

                  TestNG provides several configuration annotations that allow you to define setup and teardown methods for different levels of test execution. These annotations help you perform specific actions before and after test suites, tests, classes, and methods. Let's explore each of these annotations in detail.

                  2.2.1 @BeforeSuite and @AfterSuite

                  The @BeforeSuite and @AfterSuite annotations are used to define setup and teardown methods that run before and after the entire suite execution, respectively. These methods are executed only once per suite.

                  Example:

                  java
                  import org.testng.annotations.BeforeSuite; import org.testng.annotations.AfterSuite; public class SuiteLevelConfig { @BeforeSuite public void beforeSuiteSetup() { // Perform setup steps before the suite System.out.println("BeforeSuite: Setting up the suite"); } @AfterSuite public void afterSuiteTeardown() { // Perform teardown steps after the suite System.out.println("AfterSuite: Tearing down the suite"); } }

                  2.2.2 @BeforeTest and @AfterTest

                  The @BeforeTest and @AfterTest annotations are used to define setup and teardown methods that run before and after each test tag in the TestNG XML configuration file, respectively. These methods are executed once per test tag.

                  Example:

                  java
                  import org.testng.annotations.BeforeTest; import org.testng.annotations.AfterTest; public class TestLevelConfig { @BeforeTest public void beforeTestSetup() { // Perform setup steps before each test System.out.println("BeforeTest: Setting up the test"); } @AfterTest public void afterTestTeardown() { // Perform teardown steps after each test System.out.println("AfterTest: Tearing down the test"); } }

                  2.2.3 @BeforeClass and @AfterClass

                  The @BeforeClass and @AfterClass annotations are used to define setup and teardown methods that run before and after each test class, respectively. These methods are executed once per test class.

                  Example:

                  java
                  import org.testng.annotations.BeforeClass; import org.testng.annotations.AfterClass; public class ClassLevelConfig { @BeforeClass public void beforeClassSetup() { // Perform setup steps before the class System.out.println("BeforeClass: Setting up the class"); } @AfterClass public void afterClassTeardown() { // Perform teardown steps after the class System.out.println("AfterClass: Tearing down the class"); } }

                  2.2.4 @BeforeMethod and @AfterMethod

                  The @BeforeMethod and @AfterMethod annotations are used to define setup and teardown methods that run before and after each test method, respectively. These methods are executed once per test method.

                  Example:

                  java
                  import org.testng.annotations.BeforeMethod; import org.testng.annotations.AfterMethod; public class MethodLevelConfig { @BeforeMethod public void beforeMethodSetup() { // Perform setup steps before each test method System.out.println("BeforeMethod: Setting up the method"); } @AfterMethod public void afterMethodTeardown() { // Perform teardown steps after each test method System.out.println("AfterMethod: Tearing down the method"); } }


                  2.3. Additional Annotations:

                  • @DataProvider
                  • @Parameters
                  • @Factory
                  • @Listeners

                  3. TestNG Test Configuration

                  TestNG provides a flexible and powerful way to configure your test execution through XML configuration files. In this tutorial, we will explore the different levels of test configuration available in TestNG: XML configuration, suite configuration, test configuration, class configuration, and method configuration.

                  3.1. TestNG XML Configuration

                  The TestNG XML configuration file allows you to define the overall configuration of your test suite. It serves as the entry point for configuring and executing your tests. Here are the key aspects of TestNG XML configuration:

                  • Test Suite: The XML configuration file represents a test suite, which can contain multiple test tags.
                  • Test Classes: Within each test tag, you can specify the classes to be included for test execution.
                  • Test Parameters: You can define parameters at the suite level and pass them to your test methods or classes.
                  • Parallel Execution: TestNG XML allows you to specify parallel execution settings, such as parallel test execution, thread count, and parallel test instances.

                  Example TestNG XML Configuration (testng.xml):

                  xml
                  <!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"> <suite name="MyTestSuite" parallel="tests" thread-count="5"> <test name="LoginTests" preserve-order="true"> <parameter name="username" value="testuser" /> <parameter name="password" value="testpassword" /> <classes> <class name="com.example.LoginTest" /> </classes> </test> <test name="RegistrationTests"> <classes> <class name="com.example.RegistrationTest" /> </classes> </test> </suite>

                  3.2. Suite Configuration

                  The suite configuration allows you to customize the behavior of a specific test suite. It is defined within the <suite> tag in the XML configuration file. Here are some common settings you can configure at the suite level:

                  I. Suite Name: You can set a name for your test suite using the name attribute.

                  II. Suite Parameters: You can define parameters specific to the suite using the <parameter> tag.

                  Example for Suite Parameters:

                  Here's an example that demonstrates how to use Suite Parameters in TestNG:

                  java
                  import org.testng.annotations.Test; import org.testng.annotations.BeforeSuite; import org.testng.annotations.Parameters; public class SuiteParametersExample { @BeforeSuite @Parameters({ "browser", "environment" }) public void setupSuite(String browser, String environment) { System.out.println("Suite Setup - Browser: " + browser + ", Environment: " + environment); // Additional setup logic for the suite } @Test public void testMethod() { System.out.println("Executing testMethod()"); // Test logic goes here } }

                  In the above example, we have a @BeforeSuite annotated method called setupSuite. The @Parameters annotation is used to specify the suite-level parameters. In this case, we have defined two parameters: browser and environment. The values for these parameters are specified in the TestNG XML configuration file (testng.xml).

                  To use Suite Parameters, you need to define them in the TestNG XML configuration file as shown below:

                  xml
                  <!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"> <suite name="MyTestSuite" parallel="tests" thread-count="5"> <parameter name="browser" value="Chrome" /> <parameter name="environment" value="Production" /> <test name="LoginTests"> <classes> <class name="com.example.SuiteParametersExample" /> </classes> </test> </suite>

                  In the XML configuration above, we have defined the suite parameters using the <parameter> tag within the <suite> tag. Each parameter has a name and a value associated with it.

                  When you execute the test suite, TestNG will inject the values specified in the XML configuration into the setupSuite method's parameters. In this example, the browser parameter will be set to "Chrome" and the environment parameter will be set to "Production". You can then use these values within the setupSuite method or any other suite-level methods as needed.


                  III. Suite Level Listener: You can specify a listener class at the suite level to handle suite-level events, such as onStart and onFinish.

                  Example Code for Suite Level Listener:

                  Here's an example that demonstrates how to use a Suite Level Listener in TestNG:

                  java
                  import org.testng.ISuite; import org.testng.ISuiteListener; public class SuiteListener implements ISuiteListener { @Override public void onStart(ISuite suite) { System.out.println("Suite Started: " + suite.getName()); // Additional setup logic for the suite } @Override public void onFinish(ISuite suite) { System.out.println("Suite Finished: " + suite.getName()); // Additional teardown logic for the suite } }

                  In the above example, we implement the ISuiteListener interface and override the onStart and onFinish methods. These methods will be called by TestNG when the suite starts and finishes its execution, respectively.

                  To use the Suite Level Listener, you need to specify it in the TestNG XML configuration file (testng.xml). Here's an example:

                  xml
                  <!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"> <suite name="MyTestSuite" parallel="tests" thread-count="5"> <listeners> <listener class-name="com.example.SuiteListener" /> </listeners> <test name="LoginTests"> <classes> <class name="com.example.LoginTest" /> </classes> </test> <test name="RegistrationTests"> <classes> <class name="com.example.RegistrationTest" /> </classes> </test> </suite>

                  In the above XML configuration, we have added the <listeners> tag within the <suite> tag. Inside the <listeners> tag, we specify the class name of our Suite Level Listener (com.example.SuiteListener).

                  When you execute the test suite, the onStart method will be invoked at the beginning of the suite execution, and the onFinish method will be called at the end of the suite execution. You can add your additional setup and teardown logic inside these methods.

                  By using Suite Level Listeners, you can handle suite-level events and perform any necessary actions specific to the entire suite. This can be useful for tasks such as setting up common resources, generating reports, or cleaning up after the suite execution.


                  3.3. Test Configuration

                  The test configuration allows you to configure individual tests within a test suite. It is defined within the <test> tag in the XML configuration file. Here are some common settings you can configure at the test level:

                  • Test Name: You can set a name for your test using the name attribute.
                  • Test Parameters: You can define parameters specific to the test using the <parameter> tag.
                  • Test Level Listener: You can specify a listener class at the test level to handle test-level events.

                  Example Test Configuration:

                  java
                  import org.testng.annotations.BeforeTest; import org.testng.annotations.AfterTest; public class TestConfiguration { @BeforeTest public void setupTest() { System.out.println("Executing setupTest() before the test"); // Additional setup logic goes here } @AfterTest public void teardownTest() { System.out.println("Executing teardownTest() after the test"); // Additional teardown logic goes here } }

                  3.4. Class Configuration

                  The class configuration allows you to configure specific test classes within a test. It is defined within the <class> tag in the XML configuration file. Here are some common settings you can configure at the class level:

                  • Class Name: You can specify the fully qualified name of the test class using the name attribute.
                  • Class Level Listener: You can specify a listener class at the class level to handle class-level events.

                  Example Class Configuration:

                  java
                  import org.testng.annotations.BeforeClass; import org.testng.annotations.AfterClass; public class LoginTest { @BeforeClass public void setupClass() { System.out.println("Executing setupClass() before the LoginTest class"); // Additional setup logic goes here } @AfterClass public void teardownClass() { System.out.println("Executing teardownClass() after the LoginTest class"); // Additional teardown logic goes here } @Test public void login() { System.out.println("Executing login() test method"); // Test logic goes here } }

                  3.5. Method Configuration

                  The method configuration allows you to configure individual test methods within a test class. It is defined within the <methods> tag under the <class> tag in the XML configuration file. Here are some common settings you can configure at the method level:

                  • Method Name: You can specify the name of the test method using the <include> tag.
                  • Method Level Listener: You can specify a listener class at the method level to handle method-level events.

                  Example Method Configuration:

                  java
                  import org.testng.annotations.BeforeMethod; import org.testng.annotations.AfterMethod; public class RegistrationTest { @BeforeMethod public void setupMethod() { System.out.println("Executing setupMethod() before each test method"); // Additional setup logic goes here } @AfterMethod public void teardownMethod() { System.out.println("Executing teardownMethod() after each test method"); // Additional teardown logic goes here } @Test public void registerUser() { System.out.println("Executing registerUser() test method"); // Test logic goes here } @Test public void verifyEmailConfirmation() { System.out.println("Executing verifyEmailConfirmation() test method"); // Test logic goes here } }

                  4. Parameterization in TestNG

                  Parameterization is an essential feature in TestNG that allows you to run the same test case with different sets of data. It helps in executing tests with various inputs, making your test suites more versatile and reducing code duplication. In this tutorial, we will explore different methods of parameterization in TestNG, including parameterizing test methods, test classes, and test suites.

                  4.1. Parameterizing Test Methods

                  TestNG provides the @Parameters annotation to parameterize test methods. You can define parameters in your test method and pass values to them using the TestNG XML configuration file. Here's an example:

                  java
                  import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class ParameterizedMethodExample { @Test @Parameters({ "username", "password" }) public void loginTest(String username, String password) { // Test logic using the provided username and password // Assertions, interactions, etc. } }

                  In the above example, the loginTest() method is parameterized using the @Parameters annotation. The names of the parameters ("username" and "password") are specified in the annotation, and the actual values are provided through the TestNG XML configuration file.

                  To pass values to the parameters, you need to define them in the TestNG XML configuration file as shown below:

                  xml
                  <!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"> <suite name="MyTestSuite"> <test name="LoginTests"> <parameter name="username" value="testuser1" /> <parameter name="password" value="password123" /> <classes> <class name="com.example.ParameterizedMethodExample" /> </classes> </test> </suite>

                  In the XML configuration above, the values for the "username" and "password" parameters are specified using the <parameter> tag within the <test> tag.

                  During test execution, TestNG will inject the provided values from the XML configuration into the test method parameters. This way, you can run the same test method with different data sets by configuring the values in the TestNG XML file.


                  4.2 Parameterizing Test Classes

                  TestNG also allows you to parameterize entire test classes using the @Parameters annotation. This is useful when you have multiple test methods in a class that require the same set of parameters. Here's an example:

                  java
                  import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class ParameterizedClassExample { private String username; private String password; public ParameterizedClassExample(String username, String password) { this.username = username; this.password = password; } @Test public void loginTest() { // Test logic using the provided username and password // Assertions, interactions, etc. } @Test public void profileTest() { // Test logic using the provided username and password // Assertions, interactions, etc. } }

                  In this example, the ParameterizedClassExample class is parameterized using a constructor that takes the username and password as arguments. The @Parameters annotation is used to specify the names of the parameters. The values are provided through the TestNG XML configuration file, similar to the previous example.

                  To pass values to the parameters, you need to define them in the TestNG XML configuration file as shown below:

                  xml
                  <!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"> <suite name="MyTestSuite"> <test name="LoginTests"> <classes> <class name="com.example.ParameterizedClassExample"> <parameters> <parameter name="username" value="testuser1" /> <parameter name="password" value="password123" /> </parameters> </class> </classes> </test> </suite>

                  In this XML configuration, the values for the "username" and "password" parameters are specified within the <parameters> tag for the respective test class.

                  During test execution, TestNG will instantiate the test class with the provided values, and all the test methods within the class will have access to those parameter values.


                  4.3 Parameterizing Test Suites

                  TestNG allows you to parameterize entire test suites using the <parameter> tag in the TestNG XML configuration file. This enables you to run the same suite with different configurations. Here's an example:

                  xml
                  <!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"> <suite name="MyTestSuite"> <parameter name="browser" value="chrome" /> <parameter name="environment" value="staging" /> <test name="LoginTests"> <classes> <!-- Test classes go here --> </classes> </test> </suite>

                  In this example, the parameters "browser" and "environment" are defined at the suite level using the <parameter> tag. The values for these parameters can be accessed within the test classes or methods by using the @Parameters annotation.

                  java
                  import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class SuiteParameterExample { @Test @Parameters({ "browser", "environment" }) public void loginTest(String browser, String environment) { // Test logic using the provided browser and environment // Assertions, interactions, etc. } }

                  In the above example, the loginTest() method in the SuiteParameterExample class is parameterized using the @Parameters annotation to access the suite-level parameters.

                  During test execution, TestNG will inject the parameter values from the suite configuration into the test methods or classes that require them, allowing you to run the same suite with different configurations.


                  5. TestNG Assertions

                  Assertions and reporting play a crucial role in test automation. They help validate expected outcomes and provide meaningful information about test execution. In this tutorial, we will explore how to use assertions in TestNG for result validation and how to leverage TestNG's reporting capabilities to generate detailed test reports.

                  5.1 Using Assertions in TestNG

                  TestNG provides a set of built-in assertions that you can use to validate expected results in your test cases. These assertions are part of the org.testng.Assert class. Here are some commonly used assertions:

                  • assertEquals(expected, actual): Asserts that two values are equal.
                  • assertTrue(condition): Asserts that a condition is true.
                  • assertFalse(condition): Asserts that a condition is false.
                  • assertNull(object): Asserts that an object is null.
                  • assertNotNull(object): Asserts that an object is not null.
                  • assertSame(expected, actual): Asserts that two objects refer to the same object.
                  • assertNotSame(expected, actual): Asserts that two objects do not refer to the same object.

                  Here's an example that demonstrates the usage of assertions in TestNG:

                  java
                  import org.testng.Assert; import org.testng.annotations.Test; public class AssertionExample { @Test public void testAddition() { int result = Calculator.add(2, 3); Assert.assertEquals(result, 5, "Addition failed"); } @Test public void testStringLength() { String str = "Hello, TestNG"; Assert.assertTrue(str.length() > 0, "String is empty"); } }

                  In the above example, we use the