Hey everyone, I’m really hitting a wall here and could use some help. I’m trying to set up a data-driven test in Katalon Studio. I have an Excel spreadsheet with 100 different test accounts (usernames, passwords, account numbers) that I need to cycle through to verify our signup flow.
I went into Katalon, created a new Data File under the Object Repository architecture, and successfully imported my Excel sheet. I can see all 100 rows perfectly in the data preview. Next, I went to my Test Suite, added my test case, and associated it with that Excel Data File. I even checked the “Run from row 1 to row 100” option.
When I run the Test Suite, it looks like it’s working because the test case executes exactly 100 times. But here is the problem: every single iteration uses the exact same data from the very first row! It’s just logging in with User_001 over and over again 100 times instead of moving down to row 2, row 3, etc. I tried manually changing the variable types in my script and restarting Katalon, but nothing works. Why isn’t Katalon automatically moving to the next row of data on each iteration? What am I missing?
The reason your test is repeating 100 times using only the first row’s data is a missing link in your configuration: Data Binding.
When you add a Data File to a Test Suite, Katalon’s loop engine is triggered to run the test case $N$ times (where $N$ is your number of data rows). However, unless you explicitly tell the Test Suite which Test Case Variables map to which Excel columns, your Test Case script remains hardcoded to its default values or always fetches the static index 1. Katalon will loop the execution, but it won’t dynamically inject the iterating row data into your script variables without this binding.
The Solution
To resolve this, you must map your Test Case variables to your Data File columns inside the Test Suite interface:
Open your Test Suite.
Click on the Show Data Binding button on the top right of the Test Suite panel.
In the Test Data section (middle table), add your imported Excel Data File.
In the Variable Binding section (bottom table), click Map All or manually set the Type to Data Column, select your Excel test data file under Test Data, and choose the corresponding Excel column name for each variable.
Helper Function
If you prefer a highly customizable, script-based approach where you handle data rows programmatically inside your Test Case (instead of letting the Test Suite manage the loop binding), you can use the built-in TestData class.
Here is a simple function you can use directly inside your Test Case script to dynamically fetch data for any given row index based on the current loop iteration:
import com.kms.katalon.core.testdata.TestDataFactory
import com.kms.katalon.core.testdata.TestData
/**
* Helper method to fetch cell data dynamically from a Katalon Data File
* @param dataFileName The exact name of the Data File as it appears in your Katalon File Explorer
* @param columnName The header name of the Excel column
* @param rowIndex The 1-based index of the row you want to fetch (e.g., inside a loop)
* @return String value of the cell
*/
def getExcelData(String dataFileName, String columnName, int rowIndex) {
// Find and load the Data File from Katalon's repository
TestData data = TestDataFactory.findTestData(dataFileName)
// Fetch and return the specific value
return data.getValue(columnName, rowIndex)
}
// EXAMPLE USAGE INSIDE A MANUAL LOOP (If not using Test Suite binding):
// int totalRows = TestDataFactory.findTestData("Your_Excel_Data_File_Name").getRowNumbers()
// for (int i = 1; i <= totalRows; i++) {
// String username = getExcelData("Your_Excel_Data_File_Name", "Username_Column", i)
// WebUI.setText(findTestObject('Page_Login/input_Username'), username)
// }
In Variable Binding, use Map All or manually map each variable to its matching Excel column.
Run the suite again so each iteration receives the correct row values.
Alternative approach
A script-based option using TestDataFactory.findTestData(...) and getValue(columnName, rowIndex) if you want to manually loop through rows in code instead of relying on suite binding. That approach is useful when you need custom row handling