TestNG Tutorials 47: Marking a Parameter as Optional in TestNG

Hello folks,

When we parametrize methods in a TestNG class, we must need to pass parameter values from testng xml. If we do not pass we get an exception. We will see an example below:

TestNG class:

[java]package Parameters;

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

public class ParameterTest {
@Test
@Parameters({"testParameters1","testParameters2"})
public void testMethod(String testParameters1, String testParameters2)
{
System.out.println("Paramters one for test method: "+testParameters1);
System.out.println("Paramters two for test method: "+testParameters2);
}

}
[/java]

Testng xml without parameters:

[xml]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Test1">
<classes>
<class name="Parameters.ParameterTest"></class>
</classes>
</test> <!– Test –>
</suite> <!– Suite –>
[/xml]

Output:

When we define a parameter in a method of a testng class, TestNG expects either you declare parameter as optional or pass it from testng xml. If you do not do either, you will get exception as above stating the same. 

How to set a parameter as Optional?

TestNG provides you flexibility of declaring parameters as optional. When we declare a parameter as optional, TestNG first looks in testng xml if parameter value is provided. If provided, it will use that value otherwise it will assign default value to parameter. It will not throw any exception. 

We just need to append parameter name with “@Optional” (from org.testng.annotations.Optional) annotation. Example:

[java]package Parameters;

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

public class ParameterTest {
@Test
@Parameters({"testParameters1","testParameters2"})
// I used Optional annotation with parameter declaration
public void testMethod(@Optional String testParameters1, @Optional String testParameters2)
{
System.out.println("Paramters one for test method: "+testParameters1);
System.out.println("Paramters two for test method: "+testParameters2);
}

}
[/java]

Testng xml without parameters:

I am not passing any value to parameter from testng xml here. 

[xml]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Test1">
<classes>
<class name="Parameters.ParameterTest"></class>
</classes>
</test> <!– Test –>
</suite> <!– Suite –>
[/xml]

Output:

Learn here that how TestNG assigned default values to parameters as null. Now you can even handle if value is passed and perform actions. It also helps you to skip test at run time if parameter value is not provided.

If we pass parameter value from testng xml, it will use that value. Example:

Testng xml:

[xml]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<parameter name="testParameters1" value="testParameters 1" />
<test thread-count="5" name="Test1">
<classes>
<class name="Parameters.ParameterTest"></class>
</classes>
</test> <!– Test –>
</suite> <!– Suite –>
[/xml]

Output:

Let’s learn something new here:

Now there is a catch. We declared data type of parameter as String, what happens if we declare data type as int or float or any primitive type? See in an example below:

[java]
package Parameters;

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

public class ParameterTest {
@Test
@Parameters({"testParameters1","testParameters2"})
public void testMethod(@Optional String testParameters1, @Optional int testParameters2)
{
System.out.println("Paramters one for test method: "+testParameters1);
System.out.println("Paramters two for test method: "+testParameters2);
}

}
[/java]

Testng xml without parameters:

[xml]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Test1">
<classes>
<class name="Parameters.ParameterTest"></class>
</classes>
</test> <!– Test –>
</suite> <!– Suite –>
[/xml]

Output:

 

I have seen many people facing this issue. Solution is do not use primitive data type. Use wrapper of primitive. E.g. Integer for int.

Example:

[java]
package Parameters;

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

public class ParameterTest {
@Test
@Parameters({"testParameters1","testParameters2"})
public void testMethod(@Optional String testParameters1, @Optional Integer testParameters2)
{
System.out.println("Paramters one for test method: "+testParameters1);
System.out.println("Paramters two for test method: "+testParameters2);
}

}
[/java]

Output:

Now you can see TestNG were able to pass default values as null to parameters.

How to override default value of parameters?

We see here that TestNG passes default value as null to parameters declared as Optional when value to it is not passed from testng xml. But what if you do not want default value as null. We can override default values as well.

You need to pass another parameter name with Optional annotation as an attribute whose value will be used if value of actual parameter is not passed. Example: @Optional(“optionalParames”) String testParameters1

If value of “testParameters1″ is not passed from testng xml, TestNG will see if value of “optionalParames” is passedIf it is passed, that value will be used. If none of parameter value is passed, default value will be assigned by TestNG. 

Example below:

[java]package Parameters;

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

public class ParameterTest {
@Test
@Parameters({"testParameters1","testParameters2"})
/*
* If "testParameters1" not found in testng xml use value provided for parameter "optionalParames".
* If none is present in testng xml, use null.
*/
public void testMethod(@Optional("optionalParames") String testParameters1, @Optional("optionalParames") String testParameters2)
{
System.out.println("Paramters one for test method: "+testParameters1);
System.out.println("Paramters two for test method: "+testParameters2);
}

}
[/java]

Testng xml:

[xml]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<parameter name="optionalParames" value="OptionalValue" />
<test thread-count="5" name="Test1">
<classes>
<class name="Parameters.ParameterTest"></class>
</classes>
</test> <!– Test –>
</suite> <!– Suite –>
[/xml]

Output:

Hope you have learnt new things about Optional parameters.

More about TestNG in upcoming posts. Stay tuned.

If you have any doubt, feel free to comment below.
If you like my posts, please like, comment, share and subscribe.
#ThanksForReading
#HappySelenium

2 thoughts on “TestNG Tutorials 47: Marking a Parameter as Optional in TestNG”

  1. Hi Amod,

    I am setting parameter value in testng.xml file, and accessing its value in test class class.
    When Iam running test suite using tesng.xml file parameter is working but when i am running pom.xml using maven parameter value is not accessible, its using optional value. Can you please help me on this?

Leave a Reply

Your email address will not be published. Required fields are marked *