Understanding TestNG Parameters: A Comprehensive Guide

What are TestNG Parameters?

TestNG Parameters are a powerful means to pass values to your test methods during runtime. These parameters empower you to execute the same test method with different input values, enhancing the versatility and adaptability of your tests. They play a crucial role in data-driven testing and parameterization, allowing you to explore various scenarios with minimal code duplication.

How to Run TestNG Parameters?

Running TestNG Parameters involves a systematic approach:

1.Define Parameters in the Test Method

In your test method, annotate it with @Test and include parameters using the @Parameters annotation.

@Test
@Parameters({"username", "password"})
public void loginTest(String username, String password) {
    // Your test logic using username and password
}

2.Configure TestNG XML File

Create a TestNG XML file where you define the parameter values. Here's an example:

<suite name="ParameterizedTests">
    <test name="LoginTest">
        <parameter name="username" value="john_doe" />
        <parameter name="password" value="secretpassword" />
        <classes>
            <class name="com.example.YourTestClass" />
        </classes>
    </test>
</suite>

3.Run TestNG Suite

Execute the TestNG suite using your preferred test runner or command line. TestNG will instantiate the test class and inject parameter values into the annotated test method.

Defining TestNG Parameters at the Suite Level

Sometimes, you may want to define parameters at the suite level to share common values across multiple tests. This can be achieved by placing the parameters attribute in the <suite> tag of the TestNG XML file.

<suite name="SuiteWithParameters" parallel="tests" thread-count="5">
    <parameter name="commonParameter" value="sharedValue" />
    <!-- Other configurations and test definitions -->
</suite>

Now, the commonParameter value can be accessed by any test within the suite.


Declaring Parameters at the Suite Level

In TestNG, parameters can be defined not only at the test level but also at the suite level. This means you can provide values once at the suite level and share them among multiple tests.

To illustrate this concept, let's consider a Java class containing two test methods: Sum and Diff. Both methods take two parameters and perform addition and subtraction operations, respectively.

import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class Params {
    @Test
    @Parameters({"val1", "val2"})
    public void Sum(int v1, int v2) {
        int finalSum = v1 + v2;
        System.out.println("The final sum of the given values is " + finalSum);
    }

    @Test
    @Parameters({"val1", "val2"})
    public void Diff(int v1, int v2) {
        int finalDiff = v1 - v2;
        System.out.println("The final difference of the given values is " + finalDiff);
    }
}

In the XML file, the parameters are defined at the suite level:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="TestNG Parameters Suite">
    <parameter name="val1" value="3" />
    <parameter name="val2" value="50" />
    <test name="Params">
        <classes>
            <class name="Params" />
        </classes>
    </test>
</suite>

By moving the parameter tags to the <suite> level, we've established a central place for parameter values. Running this suite will execute both Sum and Diff methods, utilizing the shared values of 3 and 50.

Extending Across Classes

Taking the concept further, let's introduce another class called Multiply with a method named mul that multiplies two numbers. This class also uses the same parameters as the Params class.

import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class Multiply {
    @Test
    @Parameters({"val1", "val2"})
    public void mul(int v1, int v2) {
        int product = v1 * v2;
        System.out.println("The Product Of Value 1 and 2 is " + product);
    }
}

The updated XML file now includes both the Params and Multiply classes:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="TestNG Parameters Suite">
    <parameter name="val1" value="3" />
    <parameter name="val2" value="50" />
    <test name="Params">
        <classes>
            <class name="Params" />
        </classes>
    </test>
    <test name="Multiply">
        <classes>
            <class name="Multiply" />
        </classes>
    </test>
</suite>

Executing this suite demonstrates the power of suite-level parameters. All three methods (Sum, Diff, and mul) run seamlessly with the shared values, emphasizing the convenience and efficiency of declaring, passing, and executing variables at a single centralized location.

Order Of Execution In TestNG XML

In TestNG, when you define parameters at both the suite and test levels, the test-level parameters take precedence over suite-level parameters. This means that the values specified at the test level will be used for the test execution, and they will override any values set at the suite level.

In your provided TestNG XML configuration:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="TestNG Parameters Suite">
   <parameter name="val1" value="3" />
   <parameter name="val2" value="50" />
   <test name="Params">
      <parameter name="val1" value="13" />
      <parameter name="val2" value="5" />
      <classes>
         <class name="Params" />
      </classes>
   </test>
</suite>

The test named "Params" has parameters specified with values "13" and "5". In this case, these values will be used during the execution of the "Params" test, and the values specified at the suite level ("3" and "50") will be overridden.

Optional Parameters

TestNG Parameters can be marked as optional, providing flexibility in test execution. If a parameter is not specified in the XML file or programmatically, TestNG will use the default value or treat it as null.

@Test
@Parameters({"optionalParam"})
public void optionalParameterTest(@Optional("defaultValue") String optionalParam