In last post, we have learnt how can we make parameterized DataProvider method in TestNG to provide test data to multiple Test methods from single DataProvider method. Let’s make it more customised.
Suppose you need to read data from external file like Excel, properties file etc in a DataProvider method. The name of external file is not constant and keep changing or you may need to pass different data sheet for execution. If external data files names are fixed , you can hard code it within script by following approach discussed in previous post. But if external data files name are not constant, you should not hard code within script.
To achieve this, we will mix concept of parameter from testng xml and DataProvider. Let’s learn it.
A DataProvider method can take an attribute of type ITestContext which can be used to read parameter value from testng xml. We will pass required data file name from testng xml to DataProvider method. If data file name changes, we can update it in testng xml. No need to make any changes in DataProvider methods.
Java Code:
package DataProvider; import java.lang.reflect.Method; import org.testng.ITestContext; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; public class CustomDataProviderWithParameter { // A data provider method which will return a required data based on Test method // name @DataProvider(name = "DataContainer") public static Object[] myDataProvider(Method m, ITestContext iTestContext) { // Getting the method name String methodName = m.getName(); switch(methodName) { case "A" : { // Getting parameter value from testng.xml to get data file name for desired method String dataFilename= iTestContext.getCurrentXmlTest().getParameter("DataFileforA"); // I am returning data file name here but you can read data file and return proper data return new String[] {dataFilename}; } case "B" : { String dataFilename= iTestContext.getCurrentXmlTest().getParameter("DataFileforB"); return new String[] {dataFilename}; } case "C" : { String dataFilename= iTestContext.getCurrentXmlTest().getParameter("DataFileforC"); return new String[] {dataFilename}; } default: return new String[] {"No Data File"}; } } // A test method @Test(dataProvider = "DataContainer") public void A(String dataFilename) { System.out.println("DatafileName for method A is " + dataFilename); } // A test method @Test(dataProvider = "DataContainer") public void B(String dataFilename) { System.out.println("DatafileName for method B is " + dataFilename); } // A test method @Test(dataProvider = "DataContainer") public void C(String dataFilename) { System.out.println("DatafileName for method C is " + dataFilename); } }
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="DataFileforA" value="methodA.xlsx" />
<parameter name="DataFileforB" value="methodB.xlsx" />
<parameter name="DataFileforC" value="methodC.xlsx" />
<test thread-count="5" name="Test">
<classes>
<class name="DataProvider.CustomDataProviderWithParameter"/>
</classes>
</test> <!– Test –>
</suite> <!– Suite –>
[/xml]
Output:
[java]
[RemoteTestNG] detected TestNG version 6.14.2
DatafileName for method A is methodA.xlsx
DatafileName for method B is methodB.xlsx
DatafileName for method C is methodC.xlsx
===============================================
Suite
Total tests run: 3, Failures: 0, Skips: 0
===============================================
[/java]
Hope, you can implement above logic and leverage more advantages of DataProvider methods.
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