TestNG Parameters Annotation Example
A TestNG based test method is like any other java method and is allowed to have parameters. @Parameters
is the TestNG annotation that allows us to pass parameters to a Test method.
In this article, I am going to show you several examples of @Parameters
annotation.
Before we start with the examples, a bit about the setup:
- I am using using Maven as the build tool and Eclipse as the IDE, version Luna 4.4.1.
- TestNG Maven Project Example will guide you on how to setup a Maven based project and run the TestNG tests.
Table Of Contents
- 1. How to use a TestNG parameter?
- 2. Null Parameter
- 3. Optional Parameter
- 4. Method with Multiple Parameters
- 5. Parameter Types
- 6. Constructor with Parameters
- 7. Configuration methods with Parameters
- 8. Parameters in a Factory method
- 9. Parameter along with TestNG Injected Objects
- 10. Parameters passed to a static method
- 11. Overriding Parameters
- 12. Inheriting Parameters
1. How to use a TestNG parameter?
- Define parameters in the
testng.xml
file. - Refer those parameters in source files using
@Parameters
annotation. @Parameters
annotation’s attributevalue
will hold the list of variables used to fill the parameters of this method- Note that
value
is an optional attribute so you can skip it and straightaway specify the list of parameters
Let’s go through an example.
First, we will define the parameter in testng.xml
using <parameter>
. In the below XML, we define parameter exampleDesc
, the name
attribute holds the name of the parameter and the value
attribute the value that we want to pass to the method.
testng.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="TestNgParametersSuite" parallel="false"> <parameter name="exampleDesc" value="TestNG Parameter Example"></parameter> <test name="TestNgParametersTest"> <classes> <class name="com.javacodegeeks.testng.parameters.TestNgParameterExample" /> </classes> </test> </suite>
The @Parameters
annotation is used for passing values to the method. In the below class, we have two test methods t1
and t2
. Both the test methods have one string parameter. You can see the methods are annotated with @Parameters
for passing the parameter value. Note that in case of t1
, we have used value
attribute to hold the list of parameter names whereas in case of method t2
, we have directly specified the parameter name without the usage of value
attribute.
TestNgParameterExample:
package com.javacodegeeks.testng.parameters; import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class TestNgParameterExample { @Parameters(value="exampleDesc") @Test public void t1(String desc) { System.out.println("t1: " + desc); } @Parameters("exampleDesc") @Test public void t2(String desc) { System.out.println("t2: " + desc); } }
You can see from the output below, the parameter value specified in the XML file is received by the test methods.
Output:
[TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\testng.xml t1: TestNG Parameter Example t2: TestNG Parameter Example =============================================== TestNgParametersSuite Total tests run: 2, Failures: 0, Skips: 0 ===============================================
2. Null Parameter
If one of your test methods takes in a parameter, but you don’t specify its value in the XML file, then the TestNG will not run the test and instead skip with an error.
testngNullParameter.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="TestNgParametersSuite" parallel="false"> <test name="TestNgParametersTest"> <classes> <class name="com.javacodegeeks.testng.parameters.TestNgParameterExample" /> </classes> </test> </suite>
When we run the above testng
XML file, it complains of using a required parameter whose value is not defined . It suggests that we either define its value in XML file or mark it as @Optional
. In the next section, we will see how to define a parameter with a default value.
3. Optional Parameter
TestNgOptionalParameterExample:
In the below example, we specify that the parameter is optional using @Optional
. TestNG will pass in a specified default value, or null
if none is specified. We specify a default value which we print in the test method.
package com.javacodegeeks.testng.parameters; import org.testng.annotations.Optional; import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class TestNgOptionalParameterExample { @Parameters("exampleDesc") @Test public void t(@Optional("TestNG Examples") String desc) { System.out.println(desc); } }
testngOptionalParameter.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="TestNgParametersSuite" parallel="false"> <test name="TestNgParametersTest"> <classes> <class name="com.javacodegeeks.testng.parameters.TestNgOptionalParameterExample" /> </classes> </test> </suite>
You can see in the below output, the optional value is printed.
Output:
[TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\testngOptionalParameter.xml TestNG Examples =============================================== TestNgParametersSuite Total tests run: 1, Failures: 0, Skips: 0 ===============================================
4. Method with Multiple Parameters
You can also define a method with multiple parameters. They need to be specified comma separated in @Parameters
annotation.
TestNgMultipleParameterExample:
package com.javacodegeeks.testng.parameters; import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class TestNgMultipleParameterExample { @Parameters({"category", "exampleDesc"}) @Test public void t1(String category, String exampleDesc) { System.out.println("t1: " + category + ":" + exampleDesc); } @Parameters(value={"category", "exampleDesc", "moreDesc"}) @Test public void t2(String category, String exampleDesc, String moreDesc) { System.out.println("t2: " + category + ":" + exampleDesc + ", " + moreDesc); } }
testngMultipleParam.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="TestNgParametersSuite" parallel="false"> <parameter name="category" value="JCG TestNG Category"></parameter> <parameter name="exampleDesc" value="TestNG Parameter Example"></parameter> <parameter name="moreDesc" value="Using value attribute"></parameter> <test name="TestNgParametersTest"> <classes> <class name="com.javacodegeeks.testng.parameters.TestNgMultipleParameterExample" /> </classes> </test> </suite>
Output:
[TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\testngMultipleParam.xml t1: JCG TestNG Category:TestNG Parameter Example t2: JCG TestNG Category:TestNG Parameter Example, Using value attribute =============================================== TestNgMultipleParametersSuite Total tests run: 2, Failures: 0, Skips: 0 ===============================================
5. Parameter Types
TestNG will automatically try to convert the value specified in testng.xml to the type of your parameter. Here are the types supported:
- String
- int/Integer
- boolean/Boolean
- byte/Byte
- char/Character
- double/Double
- float/Float
- long/Long
- short/Short
In the below example, we have method t
which takes in all the above parameters. These parameters are then defined in the testng
XML file.
TestNgParameterTypesExample:
package com.javacodegeeks.testng.parameters; import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class TestNgParameterTypesExample { @Parameters({ "pString", "pInt", "pBoolean", "pByte", "pChar", "pDouble", "pFloat", "pLong", "pShort" }) @Test public void t(String s, int i, boolean bo, byte b, char c, double d, float f, long l, short sh) { System.out.println("string: " + s + ", int: " + i + ", boolean: " + bo + ", byte: " + b + ", char: " + c + ", double: " + d + ", float: " + f + ", long: " + l + ", short: " + sh); } }
testngParameterTypes.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="TestNgParametersSuite" parallel="false"> <parameter name="pString" value="JCG" /> <parameter name="pInt" value="1" /> <parameter name="pBoolean" value="true" /> <parameter name="pByte" value="2" /> <parameter name="pChar" value="c" /> <parameter name="pDouble" value="3.0" /> <parameter name="pFloat" value="5.0" /> <parameter name="pLong" value="4" /> <parameter name="pShort" value="30" /> <test name="TestNgParametersTest"> <classes> <class name="com.javacodegeeks.testng.parameters.TestNgParameterTypesExample" /> </classes> </test> </suite>
Output:
[TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\testngParameterTypes.xml string: JCG, int: 1, boolean: true, byte: 2, char: c, double: 3.0, float: 5.0, long: 4, short: 30 =============================================== TestNgParametersSuite Total tests run: 1, Failures: 0, Skips: 0 ===============================================
6. Constructor with Parameters
The parameters can be defined even for the constructor as in the below example.
TestNgConstructorParameterExample:
package com.javacodegeeks.testng.parameters; import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class TestNgConstructorParameterExample { @Parameters("p") public TestNgConstructorParameterExample(String p) { System.out.println("TestNgConstructorParameterExample(" + p + ")"); } @Test public void t() { System.out.println("test method: t"); } }
testngConstructorParam.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="TestNgParametersSuite" parallel="false"> <parameter name="p" value="Constructor argument example"></parameter> <test name="TestNgParametersTest"> <classes> <class name="com.javacodegeeks.testng.parameters.TestNgConstructorParameterExample" /> </classes> </test> </suite>
Output:
TestNgConstructorParameterExample(Constructor argument example) [TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\testngConstructorParam.xml test method: t =============================================== TestNgParametersSuite Total tests run: 1, Failures: 0, Skips: 0 ===============================================
7. Configuration methods with Parameters
We have seen using @Parameters
annotation for the test methods and constructor. In the below example, we use it for the @BeforeTest
configuration method.
TestNgConfigParameterExample:
package com.javacodegeeks.testng.parameters; import org.testng.annotations.BeforeTest; import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class TestNgConfigParameterExample { @Parameters("param") @BeforeTest public void beforeTest(String p) { System.out.println("beforeTest parameter: " + p); } @Parameters("param") @Test public void t(String p) { System.out.println("test method t parameter: " + p); } }
testngConfigParameter.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="TestNgParametersSuite" parallel="false"> <parameter name="param" value="TestNG Parameter Example"></parameter> <test name="TestNgParametersTest"> <classes> <class name="com.javacodegeeks.testng.parameters.TestNgConfigParameterExample" /> </classes> </test> </suite>
Output:
[TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\testngConfigParameter.xml beforeTest parameter: TestNG Parameter Example test method t parameter: TestNG Parameter Example =============================================== TestNgParametersSuite Total tests run: 1, Failures: 0, Skips: 0 ===============================================
8. Parameters in a Factory method
We can also use @Parameters
annotation for a factory method like in the below example. Using the passed-in parameters, we create TestNgFactoryParameterExample
test instance.
TestFactory:
package com.javacodegeeks.testng.parameters; import org.testng.annotations.Factory; import org.testng.annotations.Parameters; public class TestFactory { @Factory @Parameters({"factory-param1", "factory-param2"}) public Object[] create(String p1, String p2) { return new Object[]{new TestNgFactoryParameterExample(p1), new TestNgFactoryParameterExample(p2)}; } }
Note that in testng
XML, we need to include the factory class TestFactory
and not the test class as TestNG uses the factory class to create test instance.
testngFactoryParam.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="TestNgParametersSuite" parallel="false"> <parameter name="factory-param1" value="Factory"></parameter> <parameter name="factory-param2" value="Example"></parameter> <test name="TestNgParametersTest"> <classes> <class name="com.javacodegeeks.testng.parameters.TestFactory" /> </classes> </test> </suite>
Output:
[TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\testngFactoryParam.xml t: parameter passed by factory=Factory t: parameter passed by factory=Example =============================================== TestNgParametersSuite Total tests run: 2, Failures: 0, Skips: 0 ===============================================
9. Parameter along with TestNG Injected Objects
In this example, we have used a parameter along with TestNG injected parameter Object ITestContext
.
TestNgParamWithInjectedObjectsExample:
package com.javacodegeeks.testng.parameters; import org.testng.ITestContext; import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class TestNgParamWithInjectedObjectsExample { @Parameters("param") @Test public void t(String p, ITestContext context) { System.out.println("parameter: " + p + ", context: " + context.getName()); } }
testngParamWithInjectedObjects.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="TestNgParametersSuite" parallel="false"> <parameter name="param" value="TestNG Parameter Example"></parameter> <test name="Parameter-Context-Test"> <classes> <class name="com.javacodegeeks.testng.parameters.TestNgParamWithInjectedObjectsExample" /> </classes> </test> </suite>
Output:
[TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\testngParamWithInjectedObjects.xml parameter: TestNG Parameter Example, context: Parameter-Context-Test =============================================== TestNgParametersSuite Total tests run: 1, Failures: 0, Skips: 0 ===============================================
10. Parameters passed to a static method
We can also define a TestNG method as a static method like the below example where beforeTest
is a static method and it also receives a parameter.
StaticMethodParameterizationExample:
package com.javacodegeeks.testng.parameters; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class TestNgStaticMethodParameterExample { @Parameters("param") @BeforeMethod public static void beforeTest(String p) { System.out.println("static beforeTest's parameter: " + p); } @Test public void t() { System.out.println("test method: t"); } }
testngStaticMethodParameter.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="TestNgParametersSuite" parallel="false"> <parameter name="param" value="TestNG Parameter Example"></parameter> <test name="TestNgParametersTest"> <classes> <class name="com.javacodegeeks.testng.parameters.TestNgStaticMethodParameterExample" /> </classes> </test> </suite>
Output:
[TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\testngStaticMethodParameter.xml static beforeTest's parameter: TestNG Parameter Example test method: t =============================================== TestNgParametersSuite Total tests run: 1, Failures: 0, Skips: 0 ===============================================
11. Overriding Parameters
We can define the parameters at <suite>
level, <test>
and <classes>
level. TestNG will try to find the parameter first in the <classes>
tag that contains the current class, and then, if it can’t find it, in the <test>
. If it can’t find it even there, it will try to find it the <suite>
.
We start the example with a testng
XML which doesn’t override the parameter. It contains two parameters tag
and param
at suite
level. We will next override it at test
and classes
level.
testngSuiteLevelParameter.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="TestNgParametersSuite" parallel="false"> <parameter name="tag" value="TestNgOverrideParamExample"></parameter> <parameter name="param" value="SuiteLevel"></parameter> <test name="DontOverrideParamTest"> <classes> <class name="com.javacodegeeks.testng.parameters.TestNgOverrideParamExample" /> </classes> </test> </suite>
This is our test class.
TestNgOverrideParamExample:
package com.javacodegeeks.testng.parameters; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeSuite; import org.testng.annotations.BeforeTest; import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class TestNgOverrideParamExample { @Parameters({"tag", "param"}) @BeforeSuite public void beforeSuite(String tag, String p) { System.out.println(tag + ": beforeSuite parameter is at " + p); } @Parameters({"tag", "param"}) @BeforeTest public void beforeTest(String tag, String p) { System.out.println(tag + ": beforeTest parameter is at " + p); } @Parameters({"tag", "param"}) @BeforeClass public void beforeClass(String tag, String p) { System.out.println(tag + ": beforeClass parameter is at " + p); } @Parameters({"tag", "param"}) @BeforeMethod public void beforeMethod(String tag, String p) { System.out.println(tag + ": beforeMethod parameter is at " + p); } @Parameters({"tag", "param"}) @Test public void t(String tag, String p) { System.out.println(tag + ": t parameter is at " + p); } }
Output:
[TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\testngSuiteLevelParameter.xml TestNgOverrideParamExample: beforeSuite parameter is at SuiteLevel TestNgOverrideParamExample: beforeTest parameter is at SuiteLevel TestNgOverrideParamExample: beforeClass parameter is at SuiteLevel TestNgOverrideParamExample: beforeMethod parameter is at SuiteLevel TestNgOverrideParamExample: t parameter is at SuiteLevel =============================================== TestNgParametersSuite Total tests run: 1, Failures: 0, Skips: 0 ===============================================
Now we override param
in test
.
testngOverrideSuiteWithTestParam.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="TestNgParametersSuite" parallel="false"> <parameter name="param" value="SuiteLevel"></parameter> <parameter name="tag" value="Example"></parameter> <test name="OverrideParamTest"> <parameter name="param" value="TestLevel"></parameter> <classes> <class name="com.javacodegeeks.testng.parameters.TestNgOverrideParamExample" /> </classes> </test> </suite>
In the following output, you can see that only beforeSuite
method prints the parameter defined at suite
level, rest of the methods print the overridden value.
Output:
[TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\testngOverrideSuiteWithTestParam.xml Example: beforeSuite parameter is at SuiteLevel Example: beforeTest parameter is at TestLevel Example: beforeClass parameter is at TestLevel Example: beforeMethod parameter is at TestLevel Example: t parameter is at TestLevel =============================================== TestNgParametersSuite Total tests run: 1, Failures: 0, Skips: 0 ===============================================
Now we will override it in classes
as well. We have two tests OverrideParamTest
and DontOverrideParamTest
. In OverrideParamTest
, we override the value in test
as well as classes
. In DontOverrideParamTest
, we override the value only in test
and not in classes
.
testngOverrideTestWithClassesParam.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="TestNgParametersSuite" parallel="false"> <parameter name="param" value="SuiteLevel"></parameter> <parameter name="tag" value="Example1"></parameter> <test name="OverrideParamTest"> <parameter name="param" value="TestLevel"></parameter> <classes> <parameter name="param" value="ClassesLevel"></parameter> <class name="com.javacodegeeks.testng.parameters.TestNgOverrideParamExample" /> </classes> </test> <test name="DontOverrideParamTest"> <parameter name="param" value="TestLevel"></parameter> <parameter name="tag" value="Example2"></parameter> <classes> <class name="com.javacodegeeks.testng.parameters.TestNgOverrideParamExample" /> </classes> </test> </suite>
In the output here, you can see, the classes
level parameter value overrides the test
defined parameter.
Output:
[TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\testngOverrideTestWithClassesParam.xml Example1: beforeSuite parameter is at SuiteLevel Example1: beforeTest parameter is at ClassesLevel Example1: beforeClass parameter is at ClassesLevel Example1: beforeMethod parameter is at ClassesLevel Example1: t parameter is at ClassesLevel Example2: beforeTest parameter is at TestLevel Example2: beforeClass parameter is at TestLevel Example2: beforeMethod parameter is at TestLevel Example2: t parameter is at TestLevel =============================================== TestNgParametersSuite Total tests run: 2, Failures: 0, Skips: 0 ===============================================
12. Inheriting Parameters
In my final example, I show that the parameter values defined in the child suites inherit values from parent suite. A child suite can also override a parameter defined at parent suite.
Our test class contains test method inheritParameters
with parameters param1
and param2
.
TestNGParamInheritenceExample:
package com.javacodegeeks.testng.parameters; import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class TestNGParamInheritenceExample { @Test @Parameters({ "param1", "param2" }) public void inheritParameters(String p1, String p2) { System.out.println("Inherited parameters: " + p1 + " " + p2); } }
parentTestng.xml
contains child suites child1Testng.xml
and child2Testng.xml
. We will override param1
in the child suites.
parentTestng.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="ParameterSuite"> <parameter name="param1" value="Parent"></parameter> <parameter name="param2" value="Suite"></parameter> <suite-files> <suite-file path="./child1Testng.xml" /> <suite-file path="./child2Testng.xml" /> </suite-files> </suite>
child1Testng.xml
overrides parameter param1
.
child1Testng.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="Child1Suite"> <parameter name="param1" value="Child1"/> <test name="InheritedParamTest"> <classes> <class name="com.javacodegeeks.testng.parameters.InheritedParamFromParentExample"/> </classes> </test> </suite>
child2Testng.xml
overrides parameter param1
. It also contains another child suite child3Testng.xml
.
child2Testng.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="Child2Suite"> <parameter name="param1" value="Child2" /> <test name="InheritedParamTest"> <classes> <class name="com.javacodegeeks.testng.parameters.InheritedParamFromParentExample" /> </classes> </test> <suite-files> <suite-file path="./child3Testng.xml" /> </suite-files> </suite>
Child suite child3Testng.xml
again overrides parameter param1
.
child3Testng.xml:
<?xml version="1.0" encoding="UTF-8"?> <suite name="Child3Suite"> <parameter name="param1" value="Child3"/> <test name="InheritedParamTest"> <classes> <class name="com.javacodegeeks.testng.parameters.InheritedParamFromParentExample"/> </classes> </test> </suite>
In the below output, you can see the child suites manage to inherit as well as override the parameter values defined parent suite.
Output:
[TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\child1Testng.xml Inherited parameters: Child1 Suite =============================================== Child1Suite Total tests run: 1, Failures: 0, Skips: 0 =============================================== [TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\child3Testng.xml Inherited parameters: Child3 Suite =============================================== Child3Suite Total tests run: 1, Failures: 0, Skips: 0 =============================================== [TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\child2Testng.xml Inherited parameters: Child2 Suite =============================================== Child2Suite Total tests run: 2, Failures: 0, Skips: 0 =============================================== [TestNG] Running: C:\javacodegeeks_ws\testngParameters\src\test\resources\parentTestng.xml =============================================== ParameterSuite Total tests run: 3, Failures: 0, Skips: 0 ===============================================
Download the Eclipse Project
In this article, I have shown you several examples of using the TestNG @Parameters
annotation.
You can download the full source code of this example here: testngParameters.zip