Iterate data using Data Binding

Hi All,

I have a testcase with 20 steps. I want to iterate steps from 14 to 20 and i want to use Data Binding concept because i have my data in excel sheet.

I have an option of using ‘for loop’. But if i implement, everytime when i execute the script it runs for total number of excel rows.

If i use data binding i can run for specific rows. Could someone please help me.

If i use for loop, irrespective of the rows it counts as 1 test in reporting. If i use data binding i will get test report based on the rows i selected in test suite . This way i can get know how many rows of data is getting passed or failed. orelse i need to verify manually.

1 Like

Hi Sudheer,

Yes, you can run a specific number of rows.

You can do that by following steps below:

  1. In the test data listview, double click a row under data iteration column.
  2. A window will pop-up and there should be three options like Run all rows, Run from row, and Run specific
    rows. In your case, select the Run from row option and then put your desired number of rows in the fields.
  3. Click OK then run your test again.

Hope that helps. . . :slight_smile:

Arnel

2 Likes

Thanks Arnel for the reply.

My requirement is, initially all the 14 steps should run, now rest of 6 steps should run based on the three options like Run all rows, Run from row, and Run specific. Which ever i specify.

Example: In my excel i have 10 rows of data.
1st run i will execute from 2 to 5
2nd run i will execute from 6 th row onwards.

As per your explanation, my test will run all 20 steps with either of the 3 run options.

Your line is quite misleading that’s why I came up with that solution. I just thought that you want to run from row 14 to row 20.

Did you try those 3 run options? I believe it will not iterate on all 20 steps.

Sorry for the confusion.

How can i run only specific steps(14 to 20) for ‘n’ times based on the requirement?

Example: 1 to 13 step should run for 1 time and 14 to 20 should for 5 times.
After successful run, report should say 5 runs passed. How can i achieve this. Please help me

Sudheer_D_J,

I do not understand what you want to achieve.

Could you show your Excel data here to us?

And could you describe what you want to do for each rows of the excel data?

I have a testcase with 20 steps. In that from step 1 to step 14, it should run 1 time and rest of the steps 15 to 20 should loop.

In my excel i have 5 rows of data.

Using Databinding in test suite, either of the run options i will run the suite.

Scenario:
Step 1
Step 2
Step 3
Step 4
Step 5
Step 6
Step 7
Step 8
Step 9
Step 10
Step 11
Step 12
Step 13
Step 14

def totalRowCount = TestDataFactory.findTestData(‘Scenarios’).getRowNumbers()

for (def row : (1…totalRowCount)){
Step 15
Step 16
Step 17
Step 18
Step 19
Step 20
}

In data binding, under “Run from now” to row i will mention row numbers 3 to 5.

So my test should run for 3 times.

But when execute it will 5*3 = 15 times.

What do you mean by the word “step”?

Is your “step” equal to a row in a Excel spread sheet?

If not, please describe what “step” means with some example code.

I mean test step in a testcase level

I understand you want to iterate over the 5 rows in the Excel spreadsheet but want to skip the first 2 rows and starts with the 3rd row. Then you can do:

...
def totalRowCount = TestDataFactory.findTestData(‘Scenarios’).getRowNumbers()
for (def row : (1…totalRowCount)){
    if (row >=3 && row < totalRowCount) {
        // do anything for a Excel row
    }
}

Is it what you want to achieve?

1 Like

This 3 to 5 rows is only an example.

  1. First execution i may run for all 5 rows
  2. Second execution i may run from 2 to 4 rows
  3. Third Execution i may run for only one specific row.

How to make the script generic?

Sorry for more questions.

I have got an impression that you want to choose rows in an ad-hoc manner. I do not see how to make a generic test case which can consume the Excel data as you want.

I would rather propose an opposite approach. If I were you, I would copy the Excel file(Original.xlsx) to make 3 distinct working Excel files (Data1.xlsx, Data2.xlsx, Data3.xlsx) for each test case execution. Before execution test case, you are to MANUALLY edit Data1, Data2, Data3 as you wish.

Thanks for your reply. I will try to use your approach.

Hi,

why not use Apache POI way to read excel file, it’s easy to print out specific rows like next
Remember this is not your solution this is only example

excel file content
1
2
3
4
5
6
7
8
9
10

TESTCASE
List excelValues = new ArrayList();
excelValues = CustomKeywords.‘readExcelRows.ReadRows.readExcelRows’(0, 10)
System.out.println(“Rows from 1 to 10”)
for (String temp : excelValues) {
System.out.print(temp + “\t”);
}

excelValues = CustomKeywords.‘readExcelRows.ReadRows.readExcelRows’(2, 5)
System.out.println(“Rows from 3 to 5”)
for (String temp : excelValues) {
System.out.print(temp + “\t”);
}

excelValues = CustomKeywords.‘readExcelRows.ReadRows.readExcelRows’(1, 4)
System.out.println(“Rows from 2 to 4”)
for (String temp : excelValues) {
System.out.print(temp + “\t”);
}

excelValues = CustomKeywords.‘readExcelRows.ReadRows.readExcelRows’(3, 4)
System.out.println(“Only row 4”)
for (String temp : excelValues) {
System.out.print(temp + “\t”);
}

KEYWORD
package readExcelRows

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.;
import org.apache.poi.xssf.usermodel.
;

import com.kms.katalon.core.annotation.Keyword

public class ReadRows {

public static final String SAMPLE_XLSX_FILE_PATH = "C:\\Users\\xxxx\\Desktop\\data\\readExcelSheet.xls";
Workbook workbook

@Keyword
public List<String> readExcelRows(int start, int end) throws IOException, InvalidFormatException{
	List<String> excelValues = new ArrayList<String>();
	workbook = WorkbookFactory.create(new File(SAMPLE_XLSX_FILE_PATH));
Sheet sheet = workbook.getSheetAt(0);

// Create a DataFormatter to format and get each cell's value as String
DataFormatter dataFormatter = new DataFormatter();

//for-each loop to iterate over the rows and columns
int startRow = 0
int endRow = 0;
for (Row row: sheet) {
	for(Cell cell: row) {
		if (startRow >= start && endRow < end){
		String cellValue = dataFormatter.formatCellValue(cell);
		//System.out.print(cellValue + "\t");
		excelValues.add(cellValue);
		}
	}
	startRow++;
	endRow++;
}

return excelValues;
}

}

not sure is this what you will?

3 Likes

@Timo_Kuisma: It’s a great solution, Timo :slight_smile:
@Sudheer_D_J: Katalon currently supports data binding at test suite level only. If a test case having test data specified from a test suite data binding, it will be repeated according to the number of data rows. Therefore, you will receive that number of test case result in the report. So, to repeat specific test steps with specific data row with one test case result in report only, Timo’s suggestion seems to be perfect. You have to write a custom keyword to read data from the file and loop some of test steps with this data group in your code. However, Katalon team is considering to build data binding at test case level. I’m not sure if it can be bound for just some steps to get one test case result in the report. It’s still being in the internal discussion without final decision. But I can promise that I’ll let you know when any change related to this data binding release :slight_smile:

1 Like

Thanks Timo for the solution … It helped me a lot

Thanks @Loan_Tran for the reply. Solution helped me a lot

hi,

nb :slight_smile:

@kazurayam @Time_Kuisma @Loan_Tran

How exactly you do that?
Eg:
My script looks like this:

WebUI.openBrowser(‘’)

WebUI.deleteAllCookies(FailureHandling.STOP_ON_FAILURE)

println(‘Cleared all the caches’)

WebUI.navigateToUrl(‘http://www.google.com’)

WebUI.maximizeWindow()

WebUI.setText(findTestObject(‘Object Repository/TextBox’), findTestData(‘DataSearchParameter’).getValue(1, 1))

Now,
I have 2 rows in my internal data sheet.
image

Finally,
I have added to test suite like this

But this only executes my test case only once.

I need to change something here in my script:
WebUI.setText(findTestObject(‘Object Repository/TextBox’), findTestData(‘DataSearchParameter’).getValue(1, 1))

Can you help me here?

hi,

cannot see any loop in your script
like this way

InternalData data = findTestData('Login/LoginTestData')

for (def index : (0..data.getRowNumbers() - 1)) {
    'Invoke Browser and Navigate to Demo Application'
    WebUI.openBrowser('')
    WebUI.navigateToUrl(GlobalVariable.URL_Application)
    'Wait till the page load'
    //WebUI.waitForPageLoad(10)´
	WebUI.click(findTestObject('LoginPage-of-DemoApplication/a_MakeAppointment'))
    'Enter the value of username (From Internal Test Data)'
	WebUI.setText(findTestObject('LoginPage-of-DemoApplication/input_username'), data.internallyGetValue("user", index))	
    'Enter the value of password (From Internal Test Data)'
    WebUI.setText(findTestObject('LoginPage-of-DemoApplication/input_password'), data.internallyGetValue("pass", index))
    'Click on Login Button\\r\\n'
    WebUI.click(findTestObject('LoginPage-of-DemoApplication/button_Login'))
    //WebUI.verifyElementPresent(findTestObject('MakeAppointmentPage/btn_BookAppointment'), GlobalVariable.SmallTimeout)
    'Close the Browser'
    WebUI.closeBrowser()
}