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:
- Using
testng.xml
configuration file. - 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