TestNG – Parameter Test (XML and @DataProvider)

In this tutorial, we will show you how to pass parameters into a @Test method, via XML @Parameters or @DataProvider.

1. Passing Parameters with XML

In this example, the properties filename is passing from testng.xml, and inject into the method via @Parameters.

TestParameterXML.java

package com.mkyong.testng.examples.parameter;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

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

public class TestParameterXML {

	Connection con;

	@Test
	@Parameters({ "dbconfig", "poolsize" })
	public void createConnection(String dbconfig, int poolsize) {

		System.out.println("dbconfig : " + dbconfig);
		System.out.println("poolsize : " + poolsize);

		Properties prop = new Properties();
		InputStream input = null;

		try {
		  //get properties file from project classpath
		  input = getClass().getClassLoader().getResourceAsStream(dbconfig);

		  prop.load(input);

		  String drivers = prop.getProperty("jdbc.driver");
		  String connectionURL = prop.getProperty("jdbc.url");
		  String username = prop.getProperty("jdbc.username");
		  String password = prop.getProperty("jdbc.password");

		  System.out.println("drivers : " + drivers);
		  System.out.println("connectionURL : " + connectionURL);
		  System.out.println("username : " + username);
		  System.out.println("password : " + password);

		  Class.forName(drivers);
		  con = DriverManager.getConnection(connectionURL, username, password);

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

}
db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mkyongserver
jdbc.username=mkyong
jdbc.password=password
testng.xml

<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
<suite name="test-parameter">

    <test name="example1">
	
	<parameter name="dbconfig" value="db.properties" />
	<parameter name="poolsize" value="10" />
		
	<classes>
	  <class name="com.mkyong.testng.examples.parameter.TestParameterXML" />
	</classes>
		
    </test>
	
</suite>

Output


dbconfig : db.properties
poolsize : 10
drivers : com.mysql.jdbc.Driver
connectionURL : jdbc:mysql://localhost:3306/mkyongserver
username : mkyong
password : password

2. Passing Parameters with @DataProvider

2.1 Review a simple @DataProvider example, passing a int parameter.

TestParameterDataProvider.java
package com.mkyong.testng.examples.parameter;

import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class TestParameterDataProvider {

	@Test(dataProvider = "provideNumbers")
	public void test(int number, int expected) {
		Assert.assertEquals(number + 10, expected);
	}

	@DataProvider(name = "provideNumbers")
	public Object[][] provideData() {

		return new Object[][] { 
			{ 10, 20 }, 
			{ 100, 110 }, 
			{ 200, 210 } 
		};
	}

}

Output


PASSED: test(10, 20)
PASSED: test(100, 110)
PASSED: test(200, 210)

2.2 The @DataProvider is support passing an object parameter. Below example shows you how to pass a Map object as parameter.

TestParameterDataProvider.java

package com.mkyong.testng.examples.parameter;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class TestParameterDataProvider {

	@Test(dataProvider = "dbconfig")
	public void testConnection(Map<String, String> map) {

		for (Map.Entry<String, String> entry : map.entrySet()) {
		  System.out.println("[Key] : " + entry.getKey() 
                              + " [Value] : " + entry.getValue());
		}

	}

	@DataProvider(name = "dbconfig")
	public Object[][] provideDbConfig() {
		Map<String, String> map = readDbConfig();
		return new Object[][] { { map } };
	}

	public Map<String, String> readDbConfig() {

		Properties prop = new Properties();
		InputStream input = null;
		Map<String, String> map = new HashMap<String, String>();

		try {
		  input = getClass().getClassLoader().getResourceAsStream("db.properties");

		  prop.load(input);

		  map.put("jdbc.driver", prop.getProperty("jdbc.driver"));
		  map.put("jdbc.url", prop.getProperty("jdbc.url"));
		  map.put("jdbc.username", prop.getProperty("jdbc.username"));
		  map.put("jdbc.password", prop.getProperty("jdbc.password"));

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		return map;

	}
	
}

Output


[Key] : jdbc.url [Value] : jdbc:mysql://localhost:3306/mkyongserver
[Key] : jdbc.username [Value] : mkyong
[Key] : jdbc.driver [Value] : com.mysql.jdbc.Driver
[Key] : jdbc.password [Value] : password
PASSED: testConnection({jdbc.url=jdbc:mysql://localhost:3306/mkyongserver, 
jdbc.username=mkyong, jdbc.driver=com.mysql.jdbc.Driver, jdbc.password=password})

3. @DataProvider + Method

This example shows you how to pass a different parameters depending on the test method name.

TestParameterDataProvider.java

package com.mkyong.testng.examples.parameter;

import java.lang.reflect.Method;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class TestParameterDataProvider {

	@Test(dataProvider = "dataProvider")
	public void test1(int number, int expected) {
		Assert.assertEquals(number, expected);
	}

	@Test(dataProvider = "dataProvider")
	public void test2(String email, String expected) {
		Assert.assertEquals(email, expected);
	}

	@DataProvider(name = "dataProvider")
	public Object[][] provideData(Method method) {

		Object[][] result = null;

		if (method.getName().equals("test1")) {
			result = new Object[][] {
				{ 1, 1 }, { 200, 200 } 
			};
		} else if (method.getName().equals("test2")) {
			result = new Object[][] { 
				{ "test@gmail.com", "test@gmail.com" }, 
				{ "test@yahoo.com", "test@yahoo.com" } 
			};
		}

		return result;

	}

}

Output


PASSED: test1(1, 1)
PASSED: test1(200, 200)
PASSED: test2("test@gmail.com", "test@gmail.com")
PASSED: test2("test@yahoo.com", "test@yahoo.com")

4. @DataProvider + ITestContext

In TestNG, we can use org.testng.ITestContext to determine what runtime parameters the current test method was invoked with. In this last example, we will show you how to pass parameters depending on the included group name.

TestParameterDataProvider.java

package com.mkyong.testng.examples.parameter;

import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class TestParameterDataProvider {

	@Test(dataProvider = "dataProvider", groups = {"groupA"})
	public void test1(int number) {
		Assert.assertEquals(number, 1);
	}

	@Test(dataProvider = "dataProvider", groups = "groupB")
	public void test2(int number) {
		Assert.assertEquals(number, 2);
	}

	@DataProvider(name = "dataProvider")
	public Object[][] provideData(ITestContext context) {

		Object[][] result = null;
	
		//get test name
		//System.out.println(context.getName());
		
		for (String group : context.getIncludedGroups()) {

			System.out.println("group : " + group);

			if ("groupA".equals(group)) {
				result = new Object[][] { { 1 } };
				break;
			}

		}

		if (result == null) {
			result = new Object[][] { { 2 } };
		}
		return result;

	}

}
testng.xml

<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
<suite name="test-parameter">

  <test name="example1">

	<groups>
		<run>
			<include name="groupA" />
		</run>
	</groups>

	<classes>
	   <class
	    name="com.mkyong.testng.examples.parameter.TestParameterDataProvider" />
	</classes>

  </test>

</suite>

Output


group : groupA

Done.

References

  1. TestNG @DataProvider
  2. TestNG ITestContext JavaDoc
  3. Connect To MySQL With JDBC Driver

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

Leave a Reply

avatar
newest oldest most voted
Saravanan
Guest
Saravanan

hi mkyoung,

this is article is awesome .And i need your inputs on running parallel testcases using paramters.

Thanks,
Saravanan Nallamuthu

Ashan Jayasundara
Guest
Ashan Jayasundara

can we call after test method when throw an exception in data provider iteration

Tarek Said
Guest
Tarek Said
Hi, just one thing: wouldn’t it be possible (and more manageable) to use 2 data providers for 2 methods? as in: public class TestParameterDataProvider { @Test(dataProvider = “numberProvider”) public void test1(int number, int expectedNumber) { Assert.assertEquals(number, expectedNumber); } @Test(dataProvider = “emailProvider”) public void test2(String email, String expectedEmail) { Assert.assertEquals(email, expectedEmail); } @DataProvider(name = “numberProvider”) public Object[][] provideNumbers() { return new Object[][] { { 1, 1 }, { 200, 200 } }; } @DataProvider(name = “emailProvider”) public Object[][] provideEmails() { return new Object[][] { { “test@gmail.com”, “test@gmail.com” }, { “test@yahoo.com”, “test@yahoo.com” }}; }
lixiao
Guest
lixiao

If I want to use the way of ITestContext, I have to config the tag of groups in the testng.xml?
I found that the ITestContext.getIncludeGroups() can not get the value of groups if there is no testng.xml.

saran
Guest
saran

For your example 2 the dataprovider takes its values from the java code itself.. Is there any possibility to load these values from the testng.xml

vertika
Guest
vertika
Hi , I am new to selenium. Is there any way if we can pass two Dataproviders in one function. Please find below my code. @DataProvider(parallel = true) public static Iterator web_list (ITestContext context) throws IOException { List url = new ArrayList(); String webURL; BufferedReader br = new BufferedReader(new FileReader(“WebList.txt”)); while( (webURL = br.readLine()) != null ) { if( webURL.trim() != “”) url.add(new Object[] {webURL}); } return url.iterator(); } @DataProvider(parallel = true) public static Iterator browser_list (ITestContext context) throws IOException { List brw = new ArrayList(); String Browser; BufferedReader br = new BufferedReader(new FileReader(“BrowserList.txt”)); while( (Browser = br.readLine()) != null… Read more »
Manjyot
Guest
Manjyot

is there a way to print real arguments instead of : PASSED: parameterIntTest(TestNGTest6_3_0@dc6a77). For example desired output : PASSED: parameterIntTest(“Hello”,”123″)

Manjyot
Guest
Manjyot
Hi Mkyong, Nice post I must say. There is one problem I am facing right now. It would be great if you can help me with that : I am reading data from excel using data provider. Excel from which I am reading data is having some 25 odd columns and 250 odd rows. That means my test will be executed for 250 times with 25 arguments.. I am reading and returning Object[][] from data provider. In turn I have declare so 25 arguments in my test method For example : @Test(groups = { “webservice” }, dataProvider = “testDP”) public… Read more »
Sama
Guest
Sama
Im new to maven and testng I got an issue: I cannot get parameter from suite xml file for my test when run Maven Test. The result is this test is skipped: ——————————————————————————- Test set: TestSuite ——————————————————————————- Tests run: 1, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 0.375 sec I dont know why Anything wrong here? I appreciate so much Thank you This is my main test: hTest.java ==== package demo; import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class hTest { @Parameters({“user”}) @Test public void getUser(String user) { System.out.println(“NAME= ” + user); } } This is my suite hTest.xml This is… Read more »
Piers
Guest
Piers

Hello MyKong

Do you have a tutorial for EVERYTHING???

Pradeep
Guest
Pradeep

Is there any short hand way (thru annotation) to pass parameter value directly without the testng.xml/DataProvider ?

Tester
Guest
Tester

Try using @Optional annotation.

DQ
Guest
DQ

Thanks for sharing! For the DataProvider, do you have to hardcode all data in the Java class? Won’t that violate the use of xml configuration file?

trackback
How to Parameterized Test using xml file in testng ? « selenium online training with expert

[…] refer Link Like this:LikeBe the first to like this. Posted in: Blog, TestNG testing framework, Version1 | […]

Hemant
Guest
Hemant

This one is Awesome !!Great help:)

trackback
TestNG or JUnit | kapilvirenahuja.com

[…] the same, I was searching for a feature in JUnit that I have always found missing. TestNG provides Parameterized Testing using DataProviders. Given that I was once again asking myself a familiar question – TestNG […]

trackback
TestNG or JUnit « Scratch Pad

[…] the same, I was searching for a feature in JUnit that I have always found missing. TestNG provides Parameterized Testing using DataProviders. Given that I was once again asking myself a familiar question – TestNG […]

trackback
TestNG Tutorials | J2EE Web Development Tutorials

[…] Tutorial 6 – Parameterized Test – 1 Passing parameter (primitive value and object) for unit test. […]

Kiran C
Guest
Kiran C

I am using testng.xml to specify many different test parameters. For each test there is a name specified as part of the testng.xml format. How can I print out this name when the test method is running?