The problem involves handling empty cells and using null in 'Examples'.
Our test data is read from CSV files with various combinations, and not all values are always present in the columns (specifically benchmarks to be compared with response values).
The comparison needs to be conditional:
Yes, when you use a CSV file, it is a little harder to pre-process so that empty values are handled the way you expect. But it is possible, note that all the examples below can be tried locally, just cut and paste them into local / feature files.
First let us see how to do this in a "normal" Examples
block and see the difference later:
Feature: using nulls and inline json
Scenario Outline:
Given url 'https://reqres.in/api'
And path 'register'
And request { email: '#(email)', password: '#(password)' }
When method post
Then status 400
* print response
* match response == errorResponse
Examples:
| email! | password! | errorResponse! |
| null | null | { error: 'Missing email or username' } |
| 'aa' | 'bb' | { error: 'Note: Only defined users succeed registration' } |
Note how the column names are suffixed with !
so that things like null
are processed correctly instead of the default ''
or empty-string. But when you use a CSV as the data-source, you need to do the pre-processing manually. Fortunately this is easy by using a @setup
Scenario.
Here we use a small JavaScript function to convert rows, and then map()
. note that in the world of JavaScript, an empty string is considered false
. Of course, you can use any custom conversion logic you want. If you need to completely filter out some rows, that's easy as well, just use the JavaScript filter()
function.
Feature: converting empty cells to null from a csv
@setup
Scenario:
* def raw = read('examples.csv')
* def convert = x => x || null
* def data = raw.map(x => ({ email: convert(x.email), password: convert(x.password), error: x.error }))
Scenario Outline:
Given url 'https://reqres.in/api'
And path 'register'
And request { email: '#(email)', password: '#(password)' }
When method post
Then status 400
* print response
* match response == { error: '#(error)' }
Examples:
| karate.setup().data |
For the above example, the contents of examples.csv
are the following:
email,password,error
,,Missing email or username
aa,bb,Note: Only defined users succeed registration
And for completeness, the other way of "looping" in the Karate world is this way:
Feature: looping over a json array converted from a csv
Scenario:
* def raw = read('examples.csv')
* def convert = x => x || null
* def data = raw.map(x => ({ email: convert(x.email), password: convert(x.password), error: x.error }))
* call read('@register') data
@ignore @register
Scenario:
Given url 'https://reqres.in/api'
And path 'register'
And request { email: '#(email)', password: '#(password)' }
When method post
Then status 400
* print response
* match response == { error: '#(error)' }