TestNG @Parameters Example

In this post we will learn about how to parameterize your TestNG tests using TestNG @Parameters annotation which is used to pass simple primitive parameters from configuration file to test methods. These parameters are defined in suite [testng.xml] file. Let’s get going.


In TestNG, there are primarily two popular ways to pass parameters to your tests in order to do data-driven testing:

1) Using @Parameters annotation on test methods + declaring parameters in testng.xml.
This approach is useful if parameters to be passed are simple primitive types like int, String,..etc.

2) Using @DataProvider
When you want to pass complex parameters, then @DataProvider is the way to go.

Let’s consider a simple calculator class:

package com.websystique.testng;

public class Calculator {

	public int add(int a, int b){
		return a+b;
	}

	public int subtract(int a, int b){
		return a-b;
	}
	
	public int multiply(int a, int b){
		return a * b;
	}

	public int divide(int a, int b){
		return a/b;
	}

	public int squaresum(int a, int b){
		return a*a + b*b;
	}

}

We will test all of these methods. Let’s write a trivial test class for the same.

package com.websystique.testng;

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

public class TestNGParametersExample {

	@Parameters({ "number1", "number2", "sum" })
	@Test
	public void testAdd(int number1, int number2, int sum) {
		Calculator calculator = new Calculator();
		Assert.assertEquals(calculator.add(number1, number2), sum);
	}

	@Parameters({ "number1", "number2", "difference" })
	@Test
	public void testSubtract(int number1, int number2, int difference) {
		Calculator calculator = new Calculator();
		Assert.assertEquals(calculator.subtract(number1, number2), difference);
	}

	@Parameters({ "number1", "number2", "multiplication", "global_count" })
	@Test
	public void testMultiply(int number1, int number2, int multiplication, int global_count) {
		Calculator calculator = new Calculator();
		for (int i = 0; i < global_count; i++) {
			Assert.assertEquals(calculator.multiply(number1, number2), multiplication);
		}
	}

	@Parameters({ "number1", "number2", "division" })
	@Test
	public void testDivide(int number1, int number2, int division) {
		Calculator calculator = new Calculator();
		Assert.assertEquals(calculator.divide(number1, number2), division);
	}

	@Parameters({ "number1", "number2", "squaresum" })
	@Test
	public void testSquareSum(int number1, int number2, @Optional("925") int squaresum) {
		Calculator calculator = new Calculator();
		Assert.assertEquals(calculator.squaresum(number1, number2), squaresum);
	}

}

Above test class is little bit different than traditional test classes in the sense that each test now accepts parameters. So instead of using hard-coded values right in middle of test, we supply parameter, against which assertions will be done.

We will provide the parameter values and expected result right from testng.xml to the test methods using @Parameters annotation.

Below is a sample testng.xml file used in our example.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="simple_suite">

 	<parameter name="global_count" value="10" />

    <test name="calc">
    	<parameter name="number1"  value="30" />
    	<parameter name="number2"  value="5" />
    	<parameter name="sum"  value="35" />
    	<parameter name="difference"  value="25" />
    	<parameter name="multiplication"  value="150" />
    	<parameter name="division"  value="6" />
        <classes>
            <class name="com.websystique.testng.TestNGParametersExample"/>
        </classes>
    </test>
 
</suite>

Look at above testng.xml. Content of above file is usual testng.xml content but with some additional information. We are passing parameters this time using <parameter/> tags. Here we have declared one suite-level parameter named global_count and six test level parameters. All these 7 parameters will now be available in out test methods when using @Parameters annotation.

It’s worth to remember that this way of parameter passing is limited to primitive data types. For complex objects, we need to look at DataProvider.

If you review the Test class, each method is annotated with @Parameters. The values mentioned in @Parameters annotations are directly mapped to the parameters in test methods and are passed by testng.xml. testAdd, testSubtract, testMultiply & testDevide each works on parameters which are declared in testng.xml. But with testSquaresum method, you can see that we are using a parameter squaresum which is not declared in testng.xml. It is optional and is represented by @Optional annotation. We use Optional when the value is not necessarily specified as parameter in testNG.xml. In case testng.xml contains a parameter with the same name, the value declared in testng.xml will be used in test method parameter. But in case a parameter is not declared, it’s Optional value mentioned in method parameter will be taken into account.

Let’s run above suite.

– In case you are using TestNG eclipse plugin, select testng.xml –>right click–> Run As –> TestNG suite
– In case you are using maven , perform mvn clean test on command line.

Following is the outcome:
TestNGParameters_img1

[TestNG] Running:
  E:\workspace7\TestNGAnnotationsExample\src\test\resources\testng.xml


===============================================
simple_suite
Total tests run: 5, Failures: 0, Skips: 0
===============================================

That’s it.

References