In this post i am going to discuss how we can do data driven testing while doing BDD – Cucumber based Framework implementation.
Pre-requisites:
Before you proceed, you will need to know the following
- Writing Features
- Maven
- Cucumber framework
- Basic parameterization technique in cucumber feature file
In my application under test, i am building a script to test Account Transfer function
This is how my Maven project structure looked like at the end:

The excel file in which i’ve saved the Test data

My Feature file
Note that i’ve parameterized the test data such as customer ID, account transfer details etc. as s “row_Index”
Value for the row Index is provided in the Examples. 1 and 2 corresponds to excel row#2 and 3 (row#1 being header row)
These values are picked up by Step Definition class file and available as parameter for all the corresponding annotated functions (@Given, @when etc. wherever applicable. Refer to feature file screenshot below)
What happens next? First take a look at the Feature file screenshot below and then we will proceed to next section

So as i said above, row_index value is available as parameter for my stepDefinition class which looks like below:
public class AccountTransfer {
WebDriver sunViewDriver;
POMSunViewLoginPage l;
POMTreasuryDBPage t;
POMTransferCenterPage ct;
public List <hashmap<string,string>> dataSet;
public AccountTransfer(){
File file = new File("C:/Selenium/JarFiles/chromedriver.exe");
System.setProperty("webdriver.chrome.driver", file.getAbsolutePath());
sunViewDriver = new ChromeDriver();
sunViewDriver.get("https://wholesaleportal-itca.suntrust.com/SunView/user/login?contextType=external&username=string&initial_command=NONE&password=secure_string&challenge_url=https%3A%2F%2Fwholesaleportal-itca.suntrust.com%2FSunView%2Fuser%2Flogin&request_id=6651191237148972048");
dataSet = DataHelper.readExcelDatafromFile("C://Selenium//TestData//AccountTransfer.xlsx", "Sheet1");
}
@Given("^Login to SunView as \"(.*?)\" customer$")
public void login_to_SunView_as_customer(String excelDataRow) throws Throwable {
//access the first hashmap in the List
int dataRow = Integer.parseInt(excelDataRow)-1;
l = new POMSunViewLoginPage(sunViewDriver);
//Make sure that they key name matches with column name you provided on header row in Excel
l.loginToSunView(dataSet.get(dataRow).get("customerID"), dataSet.get(dataRow).get("userID5x"), dataSet.get(dataRow).get("password5x_SunView"));
sunViewDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
}
@When("^user provides provides account transfer data as in \"(.*?)\"$")
public void user_provides_provides_account_transfer_data_as_in(String excelDataRow) throws Throwable{
//access the first hashmap in the List
int dataRow = Integer.parseInt(excelDataRow)-1;
t = new POMTreasuryDBPage(sunViewDriver);
ct = new POMTransferCenterPage(sunViewDriver);
t.clickOnTransfers_SingleTransfer();
ct.createSingleTransfer(dataSet.get(dataRow).get("FromAccount"), dataSet.get(dataRow).get("ToAccount"),dataSet.get(dataRow).get("Amount"), dataSet.get(dataRow).get("Date"), dataSet.get(dataRow).get("Frequency"), dataSet.get(dataRow).get("RecurringSchedule"), dataSet.get(dataRow).get("NumberOfPaymentsOption"), dataSet.get(dataRow).get("SendTotalTransfers"), dataSet.get(dataRow).get("EndOnThisDate"), dataSet.get(dataRow).get("Options"), dataSet.get(dataRow).get("Memo"));
}
@When("^Submits the transfer$")
public void submits_the_transfer() throws Throwable {
ct.PreviewTransfer();
}
@Then("^That Transfer should be successful$")
public void that_Transfer_should_be_successful() throws Throwable {
ct.validateTransfer();
ct.searchTransferToVerifySuccessfullSubmit();
t.clickOnTreasuryDashboard();
t.logoutOfSunView();
}
}
So as you can see in the above code, I have created a List variable that holds hashmaps in it. Then i am calling a excel reading function by passing it the file location and sheet name as parameters, which is nothing but the location where i’ve saved my Test data excel fie. The List that the function returns is saved in my local List variable.
So now, lets get into the details of excel Reading function and how it is implemented.
In the Data Helper package i’ve a class file in which i have the excel reading function. Step by step details of how it is working given below:
- Declared a new List Object that holds a collection of HashMaps
- Using the Apache POI functions, I am picking the excel file, navigating to the required sheet
- Declared a Variable of type Row called HeaderRow and hardcoded it to point to row#0, i.e the first row of my excel that has header details aka column names
- Enter the for loop to iterate the rows
- Now, i declared a HashMap object which holds Key and its values in String format
- Why declare HashMap object inside the For loop? Because i want every row of excel data to be saved in a unique HashMap objects
- Enter the for loop to iterate the column
- notice that the “KEY” part of the hashmap always refers to the header row and picks the corresponding column’s cell value
- notice that the “VALUE” part of the hashmap refers the current Row- current column (current as in for loop’s iteration)
- Exit the Column-Iterating for loop
- Add the hashmap into the List object bucket
- Repeat the step4 to 11 as many # of times as the # of rows are there in excel file
- Exit the Row for loop
- Finally, Return the List object
Below is the code:
public class DataHelper {
public static HashMap<String,String> storeValues = new HashMap<String, String>();
public static List<HashMap<String,String>> readExcelDatafromFile(String filePath, String sheetName){
//create Java List to store Hashmaps
List <HashMap<String,String>>excelData = new ArrayList<>();
try{
FileInputStream fs = new FileInputStream(filePath);
XSSFWorkbook wb = new XSSFWorkbook(fs);
XSSFSheet sheet = wb.getSheet("Sheet1");
//catch header row, so that you can use it as Key for your hashmap
Row HeaderRow = sheet.getRow(0);
for(int r = 1; r<=sheet.getPhysicalNumberOfRows();r++){
Row CurrentRow = sheet.getRow(r);
//each row of data is stored in new hashmap
HashMap<String,String> currentRowMap = new HashMap<String,String>();
for(int c=0;c<CurrentRow.getPhysicalNumberOfCells();c++){
Cell CurrentCell = CurrentRow.getCell(c);
System.out.print(CurrentCell.getStringCellValue() + "\t");
currentRowMap.put(HeaderRow.getCell(c).getStringCellValue(),CurrentCell.getStringCellValue());
// i.e hashmap<key, value> = <row(0)column(c), row(1)column(c)>
}
excelData.add(currentRowMap);
}
wb.close();
fs.close();
}
catch(Exception e){
e.printStackTrace();
}
return excelData;
}
}
Let me show you pictorially what this hashmaps look like

And this is how the List Object excelData looks like

So in the below code(extracted from StepDefinition package), I’m essentially using the dataRow variable to access the hashmap#1, 2 etc… And then, .get(“key”) function access the Keys like customerID, UserID etc and fetches its values
@Given("^Login to SunView as \"(.*?)\" customer$")
public void login_to_SunView_as_customer(String excelDataRow) throws Throwable {
//access the first hashmap in the List
int dataRow = Integer.parseInt(excelDataRow)-1;
l = new POMSunViewLoginPage(sunViewDriver);
//Make sure that they key name matches with column name you provided on header row in Excel
l.loginToSunView(dataSet.get(dataRow).get("customerID"), dataSet.get(dataRow).get("userID5x"),
Finally the TestRunner class. I’m not going in detail here. There is hardly any change to this class file. It is a standard one
package testConfig;
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
@RunWith (Cucumber.class)
@CucumberOptions (
features = "src/test/java/Features",
glue = "stepDefinition",
plugin = {
"pretty",
"html:target/cucmber",
}
)
public class AccountTransferTest {
}
