userpal
userpal

Reputation: 1523

In Robot Framework, how to perform data-driven testing by creating a separate test case for each line of data in a text file?

In Robot Framework, we can use Test Template to perform data-driven testing. However, in this method, the number of test cases are fixed. We are not able to add new test cases on-the-fly.

Let's say I have a CSV text file, data.txt:

data-1a, data-1b, data-1c
data-2a, data-2b, data-2c
....
data-Na, data-Nb, data-Nc

The number of lines in the CSV file will change from time to time.

In my Robot Framework test case file, I will read this CSV file. Let's say there are N lines of data in that file, I would like to create N test cases, each using 1 line of data from that file as argument.

Is it possible to do this in Robot Framework?

Upvotes: 4

Views: 6952

Answers (4)

Vernon Crabtree
Vernon Crabtree

Reputation: 19

Check out https://pypi.org/project/RobotFramework-Examples/ This library lets you read the data, then refer to it for automatic test-case generation.

This should work:

*** Settings ***
Library    OperatingSystem
Library    Examples    autoexpand=Off
Suite Setup      Setup this suite

*** Test cases ***
My test with examples for ${column1}
    Log    Hello ${column2}, welcome to ${column3}    console=True
    
    Examples:    column1    column2    column3    --
          ...    @{test data}

*** Keywords ***
Setup this suite
    ${fileContents}=   Get File    data.txt
    ${test data}       Evaluate    re.split("\n|,", $filecontents)   modules=re
    Expand test examples

Upvotes: 0

Nandeesh Bijoor
Nandeesh Bijoor

Reputation: 173

I feel below one is the better approach.

Create two libraries one for reading the csv data and another for getting the number of lines like below.

csvLibrary.py

 1 import csv
 2 class csvLibrary(object):
 3
 4     def read_csv_file(self, filename):
 5         '''This creates a keyword named "Read CSV File"
 6
 7         This keyword takes one argument, which is a path to a .csv file. It
 8         returns a list of rows, with each row being a list of the data in
 9         each column.
 10         '''
 11         data = []
 12         with open(filename, 'rb') as csvfile:
 13             reader = csv.reader(csvfile)
 14             for row in reader:
 15                 data.append(row)
 16         return data

csvLibraryNoOfRows.py

1 import csv
2 class csvLibraryNoOfRows(object):
3
4     def csv_length(self, filename):
5         '''This creates a keyword named "CSV Length"
6
7         This keyword takes one argument, which is a path to a .csv file. It
8         returns a list of rows, with each row being a list of the data in
9         each column.
10         '''
11         length=0
12         with open(filename, 'rb') as csvfile:
13             reader = csv.reader(csvfile)
14             for row in reader:
15                 length+=1
16         return length

Include these two libraries in your test files. Using length, lets say "N" you can get the row data/cell data with the help of :FOR ${index} IN RANGE ${csvlength}

Example code is below.

Library        csvLibrary.py
Library        csvLibraryNoOfRows.py

*** Test Cases ***

Reading a csv file
${csvdata}=    read csv file   sample.csv
${csvlength}=   csv length  sample.csv
:FOR    ${index}    IN RANGE    ${csvlength}
    \   log ${csvdata[${index}]}

Upvotes: 1

Bryan Oakley
Bryan Oakley

Reputation: 385850

There is no way to directly do what you want. What you could do instead is write a script that reads your data file and auto-generates a robot test suite based on that data. The script that you use to run your tests could first run this other script to create the test file before running it.

You could also create the test suite via a suite setup, though I don't think I recommend doing it that way, as I don't think there's anything to gain and it makes your suite more complex.

Upvotes: 1

Richard Smith
Richard Smith

Reputation: 66

I am not sure if you are really looking to create separate Test Cases (ie. with separate PASS / FAIL status etc in the output report), or simply looking to repeat a sequence of test steps using a set of data?

If the latter, you can easily read in lines from external files using the OperatingSystem library, parse the contents of the file using the String library, then repeatedly call a user keyword with the contents of each line.

| *** Settings ***
| Library | OperatingSystem | WITH NAME | os |
| Library | String | WITH NAME | str |

| *** Test Cases *** |
| Read Data From File |
| | ${fileContents}= | os.Get File | data.txt |
| | ${rows}= | str.Split To Lines | ${fileContents} |
| | :FOR | ${row} | IN | @{rows} |
| |      | ${cols}= | str.Split String | ${row} | , |
| |      | My Test Keyword | @{cols} |

| *** Keywords *** |
| My Test Keyword |
| | [Arguments] | @{fields} |
| | Log Many | ${fields} |

The first failure of My Test Keyword would normally fail the entire Read Data From File test case. If you wanted to run as many as possible, and then collate the results, use the Run Keyword And Ignore Error keyword from the BuiltIn library.

Upvotes: 4

Related Questions