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:

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);
	}
	
}

Testng xml without parameters:

<?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 -->

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:

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);
	}
	
}

Testng xml without parameters:

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

<?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 -->

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 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 -->

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:

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);
	}
	
}

Testng xml without parameters:

<?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 -->

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:

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);
	}
	
}

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:

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);
	}
	
}

Testng 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 -->

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

Author: Amod Mahajan

My name is Amod Mahajan and I am an IT employee with 4+ years of experience in Software testing and staying in Bengaluru. My area of interest is Automation testing. I started from basics and went throw so many selenium tutorials. Thanks to Mukesh Otwani as his tutorials are easy and cover basics to advance. I have habit of exploring concepts by deep diving. I used to make notes. I thought of sharing my knowledge through posts and now I am here. #KeepLearning #ShareLearning