Example of TestNG test method parameters

0

In this article, I will show you how we can inject parameter values to a test method.

This is called parameterization and is one of the important features of TestNG as it allows a test method to have parameters.

One can pass parameter values to test methods as arguments following the below methods:

  1. Using testng.xml configuration file.
  2. Through DataProviders

This example is about the first method where we define the parameter and its value in testng.xml.

Parameterization through testng.xml

The parameters are defined in testng.xml using the parameter element. Its name and value are specified using the attributes name and value.

simpleParamTesting.xml:

<?xml version="1.0" encoding="UTF-8"?>
<suite name="ParameterSuite">
  <parameter name="param1" value="One"></parameter>
  <parameter name="param2" value="1"></parameter>
  <test name="SimpleMethodParamTest">  	
    <classes>
      <class name="com.javarticles.testng.SimpleParameterizationExample"/>
    </classes>
  </test>
</suite>

Once the parameters are defined, you can use them in the test method using @Parameters annotation. The parameter names have to be specified in the attributes section of @Parameters annotation. If your method has more than one parameter, they need to be specified comma separated.

SimpleParameterizationExample:

package com.javarticles.testng;

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

public class SimpleParameterizationExample {
    @Parameters({"param1", "param2"})
    @Test
    public void paramExample(String p1, int p2) {
        System.out.println("Parameters: " + p1 + ", " + p2); 
    }
}

Output:

[TestNG] Running:
  C:\javarticles_ws\testNGMethodParameters\simpleParamTestng.xml

Parameters: One, 1

===============================================
ParameterSuite
Total tests run: 1, Failures: 0, Skips: 0
===============================================

Parameters defined at different scopes

Parameters can be defined at different scopes based on the need. It can be defined at suite level, test level, classes level or at the class level. If you define a parameter at suite level then all the classes defined under the suite can access it without the need of re-defining. You can also override a parameter at a lower scope. For example, in the below configuration file, we define commonParam at suite level and then override it at class level.

scopedParamTestng.xml:

<?xml version="1.0" encoding="UTF-8"?>
<suite name="ParameterSuite">
  <parameter name="suiteParam" value="suiteScoped"></parameter>
  <parameter name="commonParam" value="suiteValue"></parameter>
  <test name="MethodParamScopedTest">
  	<parameter name="testParam" value="testScoped"></parameter>
    <classes>
      <parameter name="classesParam" value="classesScoped"></parameter>
      <class name="com.javarticles.testng.TestClass1">
      	<parameter name="classParam" value="classScoped"></parameter>
      	<parameter name="commonParam" value="overridenClassValue"></parameter>
      </class>
      <class name="com.javarticles.testng.TestClass2"/>
    </classes>
  </test>
</suite>

In the above configuration file, we have defined parameters at all possible scopes. Now we will try to access those parameters in our test class. In BeforeSuite method, you can access the suite level parameters. Since this method is called before a suite starts it won’t be able to access the parameter defined at a lower level like test.

The converse is not true, that is, a parameter defined at a higher scope is accessible by a lifecycle method defined at a lower scope. For example, test method accessSuiteLevelParam is able to access the suite level parameter suiteParam.
Method overrideCommonParam accesses suite level parameter commonParam but since it is overridden at the class level, the value is overridden.

TestClass1:

package com.javarticles.testng;

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

public class TestClass1 {    
    @Parameters({"suiteParam", "commonParam"})
    @BeforeSuite
    public void beforeSuite(String param1, String param2) {
        System.out.println("Before Suite: " + param1 + ", " + param2);
    }
    
    @Parameters({"testParam"})
    @Test
    public void beforeTest(String p) {
        System.out.println("Before test: " + p);
    }
    
    @Parameters({"suiteParam"})
    @Test
    public void accessSuiteLevelParam(String p) {
        System.out.println("Access suite level param: " + p);
    }
    
    @Parameters({"commonParam"})
    @Test
    public void overrideCommonParam(String p) {
        System.out.println("Override common param example: " + p);
    }
}

TestClass2 is able to access classes level parameter classesParam.

TestClass2:

package com.javarticles.testng;

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

public class TestClass2 {
    @Parameters({"classesParam"})
    @Test
    public void accessClassLevelParam(String p) {
        System.out.println("Access class level param: " + p);
    }
}

Output:

[TestNG] Running:
  C:\javarticles_ws\testNGMethodParameters\scopedParamTestng.xml

Before Suite: suiteScoped, suiteValue
Access suite level param: suiteScoped
Before test: testScoped
Override common param example: overridenClassValue
Access class level param: classesScoped

===============================================
ParameterSuite
Total tests run: 4, Failures: 0, Skips: 0
===============================================

Parameter in a static method

One can also have static lifecycle method with parameters.

In the below example, staticBeforeMethod is a @BeforeMethod method and it accesses the parameter param

staticParamTestng.xml:

<?xml version="1.0" encoding="UTF-8"?>
<suite name="ParameterSuite">
  <test name="StaticMethodParamTest">
  	<parameter name="param" value="Hello"></parameter>
    <classes>
      <class name="com.javarticles.testng.StaticMethodParameterizationExample"/>
    </classes>
  </test>
</suite>

StaticMethodParameterizationExample:

package com.javarticles.testng;

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

public class StaticMethodParameterizationExample {
    @BeforeMethod
    @Parameters("param")
    public static void staticBeforeMethod(String parameter) {
        System.out.println("Value of parameter: " + parameter);
    }
    
    @Test
    public void staticMethodParamExample() {
        System.out.println("Test Static Param Example");
    }
}

Output:

[TestNG] Running:
  C:\javarticles_ws\testNGMethodParameters\staticParamTestng.xml

Value of parameter: Hello
Test Static Param Example

===============================================
ParameterSuite
Total tests run: 1, Failures: 0, Skips: 0
===============================================

Inherited Parameter Example

In this example, we have a parent suite that contains child suites defined by suite-file. The parameters defined at parent suite are passed onto the child suite.

parentTestng.xml:

<?xml version="1.0" encoding="UTF-8"?>
<suite name="ParameterSuite">
  <parameter name="param1" value="One"></parameter>
  <parameter name="param2" value="1"></parameter>
  <suite-files>
  	 <suite-file path="./childTestng.xml"/>
  </suite-files>
</suite>

Method inheritedParams refers to parameters defined at parent suite level.

childTestng.xml:

<?xml version="1.0" encoding="UTF-8"?>
<suite name="ChildSuite">
  <test name="InheritedParamTest">  	
    <classes>
      <class name="com.javarticles.testng.InheritedParamExample"/>
    </classes>
  </test>
</suite>

InheritedParamExample:

package com.javarticles.testng;

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

public class InheritedParamExample {
    @Test
    @Parameters({"param1", "param2"})
    public void inheritedParams(String p1, int p2) {
        System.out.println("Inherited parameters example: " + p1 + ", " + p2);
    }
}

Output:

[TestNG] Running:
  C:\javarticles_ws\testNGMethodParameters\childTestng.xml

Inherited parameters example: One, 1

===============================================
ChildSuite
Total tests run: 1, Failures: 0, Skips: 0
===============================================

[TestNG] Running:
  C:\javarticles_ws\testNGMethodParameters\parentTestng.xml


===============================================
ParameterSuite
Total tests run: 1, Failures: 0, Skips: 0
===============================================

Optional Parameter

You can also specify a parameter as an optional parameter using @Optional annotation.

optionalParmTestng.xml:

<?xml version="1.0" encoding="UTF-8"?>
<suite name="OptionalParamSuite">
<parameter name="param" value="One"></parameter>
  <test name="OptionalParamTest">  	
    <classes>
      <class name="com.javarticles.testng.OptionalParamExample"/>
    </classes>
  </test>
</suite>

In the below example, optionalParam is optional so we have added an @Optional attribute and the optional value is specified as an attribute.

OptionalParamExample:

package com.javarticles.testng;

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

public class OptionalParamExample {
    @Test
    @Parameters({"param", "optionalParam"})
    public void inheritedParams(String p1, @Optional("1") int p2) {
        System.out.println("Inherited parameters example: " + p1 + ", " + p2);
    }
}

Download Source Code

In this article, I have shown you several examples of TestNG test method parameters source code. You can download the source code here: testNGMethodParameters.zip

Share.

Leave A Reply